/************************************************************************* * 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 #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 ***********************************/