Rev 157 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/************************************************************************** Copyright Xdel Technology Pty. Ltd. 1987* Copyright (C) 1995 Embedded Solutions* All rights reserved** file: src\upload.c** purpose: Data upload functions* This module contains all the functions required to upload* data from the handheld calculators and insert the data* into the data base as well as functions and a menu to load* and unload specific data into the data base** functions* upload - Get Leg to upload* ins_data - Insert time info into data base* supload - Extended upload functions menu* tupload - Read in text team information* t_parse_number - Parse a number from a CSV line of team text* t_parse_text - Parse string from a CSV line of team text* p_del - Test for a delimiter.* tdnload - Generate team name file* dnload - Generate leg timing file* getfname - Get a filename from the user** programmer: David Purdie** revision date by reason* May 1990 Margherita Veroni* The functions to upload data have been modified* to allow leg start times to also be uploaded for* any leg. Data being uploaded which contain errors* are written to an error file** 00.0 1-Apr-94 DDP Changed tdnload() to produce a comma seperated* file. This allows external users to see the* field delimters better than tabs** 00.0 27/01/95 DDP Tidies up the program and formatted the file***************************************************************************/#include <stdio.h>#include "consts.h"#include "structs.h"#include "proto.h"/* Variable storage */char ufilename[40]; /* Name of upload file */FILE *ufile; /* Upload file stream */FILE *efile; /* Error file stream */char line[300]; /* Input line */char line_text[133]; /* Output text */int last_loaded_leg = 0; /* Last leg that was loaded */unsigned char manstart; /* Manual start time entry *///menu_table sup_menu[] = {// //{ '1', "Load team information from external file", tupload },// //{ '2', "Store team information from external file", tdnload_store },// //{ '3', "Create external team information file", tdnload },// { '4', "Create external leg data file", dnload },// { '5', "Upload time information", upload },// { 'q', "Return to main menu", 0 },// { '\0' }//};/*========================================================================** Get Leg to upload** Purpose:* This function is called to Get Leg to upload* Prompt user for leg number and start / end of leg* Open disc file* Read and parse text. Enter data into team information* Maintain error file of errors.** Parameters:* None** Returns:* Nothing**========================================================================*///void upload(void)//{// int hh, mm, ss; /* Team times */// int error = 0; /* Count of errors */// int ntms = 0; /* Number of teams uploaded */// char stend[] = "E"; /* Start or End time */// char *filename; /* Name of file to open */// char *err_filename; /* Name of an error file to open */// cur( 0, 5 );// while( TRUE )// {// leg = 0;// d_field( 0, 6, "Enter leg to upload :", D_NUMBER, 1, ( char * ) &leg, TRUE, M_UPDATE );// if( leg == 0 )// return; /* Null leg - just exit */// if( leg <= config.num_legs ) /* Valid leg number - Exit loop */// break;// beep(); /* Make a noise and wait for valid number */// }// /*// ** Save for check// */// last_loaded_leg = leg;// /*// * Find out if Start or End of leg times to be uploaded// */// do// {// d_field( 0, 7, "Start or End of leg to upload :", D_USTRING, 1, stend,// TRUE, M_UPDATE );// } while( ( stend[0] != 'S' ) && ( stend[0] != 'E' ) );// manstart = ( ( stend[0] == 'S' ) ? TRUE : FALSE );// printf( "\n" );// /*// * Locate the required data file and prepare for processing// */// filename = tprintf( "%s%d" , manstart ? "Sleg" : "leg" , leg );// ufile = fopen( filename, "rt" );// if( ufile == 0 )// {// printf( "Cannot locate data file - %s\n", filename );// beep();// sleep( 5 );// return;// }// /*// * create an error file for this leg data// * duplicate times will stored here// */// err_filename = tprintf( "%s%d.err" , manstart ? "Sleg" : "leg" , leg );// efile = fopen( err_filename, "at" );// /*// * Process each entry in the file// */// if( leg > config.num_legs )// printf( "\nUploading leg%d start information\n", leg );// while( fgets( line, 101, ufile ) )// {// if( sscanf( line, "%d %d:%d:%d", &team, &hh, &mm, &ss ) != 4 )// {// printf( "Upload error - %s", line );// error++;// }// else// {// if( !ins_data( team, hh, mm, ss ) )// error++;// ntms++;// }// }// printf( "%d errors detected. %d teams uploaded. Any key to continue ", error, ntms );// getinp();// fclose( ufile );// fclose( efile );//}/*========================================================================** Insert time info into data base** Purpose:* This helper function is called to Insert time info into data base* Read record* Read and convert time* Write record* Maintain error file* Display errors on screen** Parameters:* tm Team* hh hours* mm minutes* ss seconds** Returns:* Nothing**========================================================================*///int ins_data( int tm, int hh, int mm, int ss )//{// time_t l_time; /* Leg time */// int ok = TRUE;// /*// * Calculate the time for the team// */// l_time = conv_time( hh, mm, ss );// /*// * If an error is found - invalid team, team not found or dual time for team// * a message is output to the screen and the data is written to error file// * FALSE is returned// */// if( !valid_field( tm ) )// {// printf( "Invalid team - %d %2.2d:%2.2d:%2.2d\n", tm, hh, mm, ss );// fprintf( efile, "Invalid team - %d %2.2d:%2.2d:%2.2d\n", tm, hh, mm,// ss );// ok = FALSE;// return ( ok );// }// if( !g_record( tm, &team_buf ) )// {// printf( "Team not found -% d %2.2d:%2.2d:%2.2d\n", tm, hh, mm, ss );// fprintf( efile, "Team not found - %d %2.2d:%2.2d:%2.2d\n", tm, hh, mm, ss );// ok = FALSE;// }// if( !manstart )// { /* Normal upload */// if( team_buf.leg[leg].end > 0 && team_buf.leg[leg].end != l_time )// {// printf( "Dual time for %d - %2.2d:%2.2d:%2.2d and %s\n", tm, hh,// mm, ss, time_a( team_buf.leg[leg].end ) );// fprintf( efile, "Dual time for %d - %2.2d:%2.2d:%2.2d and %s\n",// tm, hh, mm, ss, time_a( team_buf.leg[leg].end )// ); /* write duplicate time to error file */// ok = FALSE;// return ( ok ); /* keep time already in database */// }// team_buf.leg[leg].end = l_time;// }// else// { /* Uplaod start time */// team_buf.leg[leg].start = l_time;// team_buf.leg[leg].manual = TRUE;// }// set_times( &team_buf ); /* Calc start of next leg */// ( void ) test_times( &team_buf, 0 ); /* Calc elapsed times etc */// put_team_record( tm, &team_buf );// return ( ok );//}///*========================================================================// *// * Extended upload functions menu// *// * Purpose:// * This function is called to Extended upload functions// *// * Parameters:// * None// *// * Returns:// * Nothing// *// *========================================================================*///void supload(void)//{// do_menu( "Extended data manipulation", "Select option", sup_menu ); /* Call a menu to do it *///}/*========================================================================** Read in text team information** Purpose:* This function is called to do Read in text team information* from a file** The source file is a comma seperated file and may contain the* folowing items** Team Number - Mandatory* Team Name - Mandatory* Team Catagory - Mandatory** Team Names ... - Optional** Parameters:* None** Returns:* Nothing**========================================================================*///void tupload(void)//{// int error = 0;// int i;// char *linep;// int class_count[MAX_CLASS];// int total;// cur( 0, 5 );// printf( "Read text file of team information" );// if( !getfname( "Enter name of the file to read :", ".csv" ) )// return;// printf( "\n" );// ufile = fopen( ufilename, "rt" ); /* Open the file for reading */// if( ufile == 0 )// {// printf( "Cannot locate data file - %s\n", ufilename );// beep();// sleep( 5 );// return;// }// memset ( class_count, 0, sizeof( class_count ));// /*// ** Get the data from the file// ** Read in lines one by one// */// while( fgets( line, sizeof(line) - 10 , ufile ) )// {// linep = line;// int has_data = 0;// /*// ** Skip blank lines// ** Skip leading white space// */// for ( linep = line; *linep; linep++ )// {// if ( *linep == (char)0xA0 || *linep == '"' || *linep == ',' || *linep == '\n' ||*linep == '\r')// {// continue;// }// has_data = 1;// }// if ( !has_data )// continue;// for ( linep = line; isspace( *linep ); linep++ )// {// }// if ( ! *linep )// continue;// /*// ** The first entry on the line should be team number// ** If it is not a valid team number then skip// */// if( ! t_parse_number( &linep, &team ) )// {// printf( "No team number: %-30s.\n", line );// error++;// }// else if( ! valid_field( team ) )// {// printf ( "Invalid team number: %d\n", team );// error++;// }// else// {// g_record( team, &team_buf );// /*// ** Extract a team information from the CSV file// ** These fields will be// ** - Team Name// ** - Category// ** - Member names// */// if ( t_parse_text( &linep, line_text ) )// {// strncpy (team_buf.name,line_text,MAX_TM_NAME);// if ( ! *line_text )// {// printf( "Team: %d - No Team Name:%50.50s...\n", team, line );// }// }// if ( t_parse_text( &linep, line_text ) && *line_text)// {// int cat_found = 0;// team_buf.teamclass = lookup_class( line_text, NULL );// if ( team_buf.teamclass > 0)// {// /*// ** The team has a category// ** Now flag the team as valid - it has ALL// ** the basic information// */// team_buf.flags.valid = TRUE;// cat_found =1;// if ( team_buf.teamclass < MAX_CLASS )// class_count[team_buf.teamclass]++;// }// if ( !cat_found )// {// printf( "Team: %d - Invalid category:%s\n", team,line_text );// error++;// }// }// else// {// printf( "Team: %d - No category:%50.50s...\n", team, line );// error++;// }// for( i = 0; i < MAX_MEMB; i++ )// {// if ( t_parse_text( &linep, line_text ) )// {// strncpy (team_buf.members[i].name,line_text,MAX_PERSON_NAME);// }// int age;// if ( t_parse_number( &linep, &age ) )// {// team_buf.members[i].age = age;// }// }// put_team_record( team, &team_buf );// }///*//** printf( ">>>:%s\n", line );//** if ( 'q' == getinp() ) break;//*/// }// /*// ** Display a few upload stats// */// total = 0;// for( i = 0; i < config.num_class; i++ )// {// printf( "%*s : %d\n", LEN_CLASS_NAME, config.team_class[i].full_name, class_count[i+1] );// total += class_count[i+1];// }// printf( "\n%*s : %d\n", LEN_CLASS_NAME, "Total Uploaded", total );// printf( "%*s : %d\n", LEN_CLASS_NAME, "Errors", error );// printf( "\nAny key to continue " );// getinp();// fclose( ufile );//}/*========================================================================** Parse a number from a CSV text file** Purpose:* This helper function is called to Parse line of team text** Parameters:* linep Current input source pointer* Will be updated to point to end of the field* If the field is a valid number* number Number extracted** Returns:* TRUE - Number extracted OK* FALSE - No number extracted**========================================================================*///bool t_parse_number( char **linep, int *number )//{// long lnumber;// char *work = *linep;// char *endp;// /*// ** Extract data from the CSV field// ** May need to remove quotes// ** Use temp work space// */// t_parse_text( &work, line_text);// /*// ** Expecting a number// ** strtol will remove leading white space// */// lnumber = strtol( line_text, &endp, 10 );// /*// ** A valid number ?// ** All the field must be numeric, otherwise it wasn't a number// */// if ( lnumber == 0 || *endp )// return FALSE;// *number = (int) lnumber;// *linep = work;// return TRUE;//}/*========================================================================** Parse a text field from a CSV text file** Purpose:* This helper function is called to Parse line of team text** Parameters:* linep Current input source pointer* Will be updated to point to end of the field* number Address of buffer to insert text into** Returns:* TRUE - Field extracted OK* FALSE - No field extracted**========================================================================*///bool t_parse_text( char **linep, char *text )//{// char uch;// char *textp = text;// bool quoted = FALSE;// /*// ** If we have already reached the end of the line tne indicate// ** That there is no data// */// uch = **linep;// if ( uch == '\n' || uch == '\r' || uch == '\0' )// return ( FALSE );// /*// ** Extract the next record// */// while ( TRUE )// {// uch = **linep;// /*// ** End of the field// */// if ( uch == '\n' || uch == '\r' || uch == '\0' )// break;// (*linep)++;// /*// ** Ugly character from MS CSV files// */// if ( uch == (char) 0xA0 )// {// continue;// }// if ( !quoted && uch == ',' )// {// break;// }// /*// ** An unquoted " will start scanning for a matching quote// */// if ( !quoted && uch == '"' )// {// quoted = TRUE;// continue;// }// /*// ** A quoted " may be an embedded quote or the end of a quote// */// if ( quoted && uch == '"' )// {// if ( **linep != '"' )// {// quoted = FALSE;// continue;// }// /*// ** Skip one " and pick up the next// */// (*linep)++;// }// /*// ** Save this character// */// *textp++ = uch;// }// /*// ** Clean up the extracted string// */// *textp = 0;// compact ( text );// return ( TRUE );//}/*========================================================================** Test for a delimiter.** Purpose:* This function is called to Test for a delimiter.** Parameters:* c Character to test** Returns:* TRUE if a delimter (space, tab or comma)**========================================================================*///char p_del( char *c )//{// return ( *c == ' ' || *c == '\t' || *c == ',' || *c == '\0' || *c == '\n' || *c == '\r');//}//char p_eol( char *c )//{// return ( *c == '\0' || *c == '\n' || *c == '\r' );//}/*========================================================================** Generate team name file** Purpose:* This function is called to Generate team name file in the format* that can be read by the load command** The file contains team number,Team name,Team class* The operator is prompted to enter the name of the file** Parameters:* None** Returns:* Nothing**========================================================================*///void tdnload_store(void)//{// int i;// int j;// cur( 0, 5 );// printf( "Create text file of team information" );// if( !getfname( "Enter name of the file to create :", ".csv.txt" ) )// return;// printf( "\n" );// /*// ** Open printer, with known filename// */// if( !open_printer_name( ufilename, 2000, text, NULL ) )// {// beep();// sleep( 5 );// return;// }// /*// ** Print headings// */// csv_print( "%s", "Team Number" );// csv_print( "%s", "Team Name" );// csv_print( "%s", "Class Abr");// for( j = 1; j <= config.num_legs; j++ )// {// csv_print( "%s", "Competitor Name");// csv_print( "%s", "Age");// }// csv_print("\n");// /*// * Put the data into the file// */// for( i = config.min_team; i <= config.max_team; i++ )// {// if( valid_field( i ) && g_record( i, &team_buf ) )// {// /*// ** Basic information// ** - Team number// ** - Full team name// */// csv_print( "%d", team_buf.numb );// csv_print( "%s", team_buf.name );// csv_print( "%s", team_buf.teamclass == 0 ? "" : config.team_class[team_buf.teamclass - 1].abr );// for( j = 1; j <= config.num_legs; j++ )// {// csv_print( "%s", team_buf.members[j-1].name );// csv_print( "%d", team_buf.members[j-1].age );// }// csv_print( "\n" );// }// }// close_printer();//}/*========================================================================** Generate team name file** Purpose:* This function is called to Generate team name file** The file contains team number,Team name,Team class* The operator is prompted to enter the name of the file** Parameters:* None** Returns:* Nothing**========================================================================*///void tdnload(void)//{// int i;// cur( 0, 5 );// printf( "Create text file of team information" );// if( !getfname( "Enter name of the file to create :", ".txt" ) )// return;// printf( "\n" );// ufile = fopen( ufilename, "wt" ); /* Open the file for writing */// if( ufile == 0 )// {// printf( "Cannot create data file - %s\n", ufilename );// beep();// sleep( 5 );// return;// }// /*// * Put the data into the file// */// for( i = config.min_team; i <= config.max_team; i++ )// {// if( valid_field( i ) && g_record( i, &team_buf ) )// {// fprintf( ufile, "%-5d,%-30s,%-5s\n",// team_buf.numb,// team_buf.name,// team_buf.teamclass >// 0 ? config.team_class[team_buf.teamclass - 1].abr : "" );// }// }// fclose( ufile );//}/*========================================================================** Generate leg timing file** Purpose:* This function is called to Generate leg timing file** Parameters:* None** Returns:* Nothing**========================================================================*///void dnload(void)//{// int i;// char stend[] = "E";// cur( 0, 5 );// printf( "Generate leg data files" );// while( TRUE )// {// leg = 0;// d_field( 0, 6, "Enter leg to save :", D_NUMBER, 1, ( char * ) &leg,// TRUE, M_UPDATE );// if( leg == 0 )// return; /* Null leg - just exit */// if( leg <= config.num_legs ) /* Valid leg number - exit loop */// break;// beep(); /* Make a noise and keep waiting for valid number */// }// /*// * Find out if Start or End of leg times to be saved// */// do// {// d_field( 0, 7, "Start of End of leg to save :", D_USTRING, 1, stend,// TRUE, M_UPDATE );// } while( ( stend[0] != 'S' ) && ( stend[0] != 'E' ) );// manstart = ( stend[0] == 'S' ? TRUE : FALSE );// /*// * Locate the required data file and prepare for processing// */// printf( "\n" );// sprintf( ufilename, ( manstart ? "Sleg%d" : "leg%d" ), leg ); /* Create the file name */// ufile = fopen( ufilename, "wt" ); /* Open the file for writing */// if( ufile == 0 )// {// printf( "Cannot create data file - %s\n", ufilename );// beep();// sleep( 5 );// return;// }// /*// * Write the data to the data file// */// for( i = config.min_team; i <= config.max_team; i++ )// {// if( valid_field( i ) && g_record( i, &team_buf ) )// {// if( !manstart// && ( leg <= config.num_legs && team_buf.leg[leg].end >= 0 ) )// fprintf( ufile, "%d %s\n", i,// time_a( team_buf.leg[leg].end ) );// if( manstart && team_buf.leg[leg].start >= 0 )// fprintf( ufile, "%d %s\n", i,// time_a( team_buf.leg[leg].start ) );// }// }// fclose( ufile );//}/*========================================================================** Get a filename from the user** Purpose:* This function is called to Get a filename from the user** Parameters:* prompt User prompt* ext File extension** Returns:* TRUE: all is well**========================================================================*///char getfname( const char *prompt, const char *ext )//{// /*// ** Create a default name if non is present// */// if ( ! *ufilename )// {// sprintf( ufilename, "%s%s", filebase, ext );// }// d_field( 0, 6, prompt, D_STRING, 40, ufilename, TRUE, M_UPDATE );// if( abort_flag )// return ( FALSE );// compact( ufilename );// if( ufilename[0] )// return ( TRUE );// return ( FALSE );//}/********************************* EOF ***********************************/