/************************************************************* Program: gbdetect.c detect ill code in a GuoBiao file Output lines with ill code in file "filename.err" Output corrected version in file "filename.fix", if fixable bug is detected. Note: A Chinese character in GuoBiao coding consists of two bytes. Range of byte 1: 0xA1--0xA7, 0xB0--0xF7 (BYX and CCDOS) Range of byte 2: 0xA1--0xFE (Unused range of byte 1: 0xA8--0xAF, 0xF8--0xFE) For usage, type "gbdetect" on command line (after compilation). Author: Rupert Zhu. April 25/1991. Revised: April 27/1991 Send suggestion or bug report to **************************************************************/ #include #include #include #include #define TRUE 1 #define FALSE 0 char *pgname; /* name of this program */ int s_flag = FALSE; /* command line flag for using stdin and stdout */ int name_flag = FALSE; /* indicate whether a file_name is provided */ int cntrl_count = 0; /* no. of control char not '\n' or '\r' */ int out_range_count = 0; /* no. of char between 0x80 and 0xA0 */ int shift_count = 0; /* no. of char in range but at wrong position */ int uneven_count = 0; /* no. of lines with odd number of high byte */ int bug_count = 0; /* total no. of bug characters */ char in_name[81]; /* input file name (with extension) */ char out_name[81]; /* output file name (with extension .err) */ char fix_name[81]; /* file for corrected text (with extension .fix) */ char name[81]; /* file name (without extension */ FILE *in_file; /* file to be tested */ FILE *out_file; /* file to hold error text */ FILE *fix_file; /* file to hold corrected version, if any */ void usage() { fprintf(stderr, "\t|----------------------------------------------------|\n"); fprintf(stderr, "\t| Usage: gbdetect file_name |\n"); fprintf(stderr, "\t| Lines containing bug is put in file_name.err |\n"); fprintf(stderr, "\t| If any bug is detected, a corrected version |\n"); fprintf(stderr, "\t| is created and put in file_name.fix |\n"); fprintf(stderr, "\t| Example: gbdetect CM9104A.GB |\n"); fprintf(stderr, "\t| Error text in file CM9104A.err |\n"); fprintf(stderr, "\t| Corrected text in file CM9104A.fix |\n"); fprintf(stderr, "\t|----------------------------------------------------|\n"); exit(1); } /* this does the real detecting work */ void detect() { unsigned char c, buf[10240]; int i, even = TRUE, bug = FALSE; while ( fgets(buf, 10000, in_file) != NULL ) { bug = FALSE; i = 0; while ( ( c = buf[i] ) != '\0' ) { i ++; if ( iscntrl(c) && !isspace(c) ) { bug = TRUE; /* ASCII control char */ cntrl_count ++; } if ( ( c >= 0x80 && c <= 0xA0 ) || c >= 0xFF ) { bug = TRUE; /* out of GuoBiao range */ out_range_count ++; } if ( isprint(c) || isspace(c) ) { if (!even) { bug = TRUE; /* un-even block */ uneven_count ++; } even = TRUE; /* reset at ASCII char */ } if ( c >= 0xA1 && c <= 0xFE ) even = !even; /* paired off */ if ( !even && /* c is first byte in a pair */ ((c>=0xA8 && c<=0xAF) || (c>= 0xF8 && c<=0xFE))) { bug = TRUE; /* first byte out of range */ shift_count ++; /* misplaced second byte? */ } } if (bug) { fputs(buf, out_file); fputc('\n', out_file); } } bug_count = cntrl_count + out_range_count + shift_count +uneven_count; } void fix() { int c; if ( cntrl_count || out_range_count ) { rewind(in_file); if ( (fix_file = fopen(fix_name, "wb")) == NULL ) { fprintf(stderr, "File open failed\n"); exit(1); } while ( ( c = fgetc(in_file) ) != EOF ) { if (isprint(c) || isspace(c) || (c>=0xA1 && c<=0xFE)) fputc(c, fix_file); } fprintf(stderr, "\t|------------------------------------|\n"); fprintf(stderr, "\t| A corrected version is created |\n"); fprintf(stderr, "\t| in file: %-16.15s |\n", fix_name); fprintf(stderr, "\t|------------------------------------|\n"); } if ( shift_count || uneven_count ) { fprintf(stderr, "\t|-------------------------------------|\n"); fprintf(stderr, "\t| Warning: Cannot completely fix the |\n"); fprintf(stderr, "\t| file, whether or not a corrected |\n"); fprintf(stderr, "\t| version is created |\n"); fprintf(stderr, "\t|-------------------------------------|\n"); } } /* if -s flag, use stdin and stdout; otherwise, use the name provided */ void open_file() { if ( s_flag ) { in_file = stdin; out_file = stdout; } else if ( !strcmp(in_name, out_name) || !strcmp(in_name, fix_name)) { fprintf(stderr, "\t|-------------------------------------|\n"); fprintf(stderr, "\t| Warning: Input file should not have |\n"); fprintf(stderr, "\t| extension .err or .fix |\n"); fprintf(stderr, "\t| Job aborted ! |\n"); fprintf(stderr, "\t|-------------------------------------|\n"); exit(1); } else if (name_flag) { if ((in_file=fopen(in_name, "rb")) == NULL) usage(); if ((out_file=fopen(out_name,"wb")) == NULL) { fprintf(stderr, "Cannot open out_file"); exit(1); } } } /* report to user what is done */ void message() { if (name_flag && !s_flag) { fprintf(stderr, "\t|------------------------------------|\n"); fprintf(stderr, "\t| Input_file = %-16.15s |\n", in_name); fprintf(stderr, "\t| Output_file = %-16.15s |\n", out_name); fprintf(stderr, "\t| Undue control characters = %4d |\n", cntrl_count); fprintf(stderr, "\t| Out of range characters = %4d |\n", out_range_count); fprintf(stderr, "\t| Misplaced first byte = %4d |\n", shift_count); fprintf(stderr, "\t| Un-even blocks = %4d |\n", uneven_count); fprintf(stderr, "\t| Total Bug Characters = %4d |\n", bug_count); fprintf(stderr, "\t| Job Well Done ! |\n"); fprintf(stderr, "\t|------------------------------------|\n"); } } main(argc, argv) int argc; char *argv[]; { int i; char *cp; if (argc <= 1 || argc >= 4) usage(); pgname = argv[0]; in_file = NULL; out_file = NULL; for (i=1; i