/* * Merge two files by lines. * Ignore punctuation and case in the comparison. * Optionally skip leading chars in comparison. * * * Usage: * * sortlex [-s] * * Written to use BDS C by H.Moran * Last Update: 10/9/83 (hrm) */ #include "bdscio.h" #define REV_DATE "10/9/83" #define PROC int /* PROCedure i.e. function returning no value */ #define BOOL int #define TRIAD int /* -1, 0, or +1 */ #define NATURAL unsigned /* Natural or counting numbers */ #define YES 1 #define NO 0 /* * forward declared functions */ TRIAD cmpstr(); /* * cmpstr() locals made global for speed */ char *s1, *t1; int i; /* * Globals */ FILE ibuf1, ibuf2, obuf; int lcount; NATURAL maxlines; NATURAL skipchars; char linbuf1[300], linbuf2[300]; PROC main(argc, argv) char **argv; { int maxwidth, width, wideline; BOOL mor_in_1, mor_in_2; int i; skipchars = maxwidth = 0; if ( argc < 3 || argc >5 ) abort("incorrect number of arguments"); if ( fopen(argv[1], &ibuf1) == ERROR ) { printf("Can't open %s\n", argv[1]); exit(1); } if ( fopen(argv[2], &ibuf2) == ERROR ) { printf("Can't open %s\n", argv[2]); exit(1); } if ( fcreat(argv[3], &obuf) == ERROR ) { printf("Can't create %s\n", argv[3]); exit(1); } for ( i = 4; i < argc; ++i ) { /* decode options */ if ( argv[i][0] != '-' ) abort("expecting '-' option"); else { /* option flag detected */ if ( tolower(argv[i][1]) == 'l' ) maxlines = atoi(&argv[i][2]); else if ( tolower(argv[i][1]) == 's' ) skipchars = atoi(&argv[i][2]); else /* invalid option */ abort("unrecognized option"); } } lcount = 0; if ( ! fgets(linbuf1, &ibuf1) ) abort("First File is Empty"); if ( ! fgets(linbuf2, &ibuf2) ) abort("Second File is empty"); mor_in_1 = mor_in_2 = YES; do { if ( cmpstr(linbuf1, linbuf2) < 0 ) { fputs(linbuf1, &obuf); ++lcount; if ( mor_in_1 ) if ( ! fgets(linbuf1, &ibuf1) ) { mor_in_1 = NO; linbuf1[0] = 0xff; linbuf1[1] = '\0'; /* Greatest Possible String */ } } else { fputs(linbuf2, &obuf); ++lcount; if ( mor_in_2 ) if ( ! fgets(linbuf2, &ibuf2) ) { mor_in_2 = NO; linbuf2[0] = 0xff; linbuf2[1] = '\0'; /* Greatest Possible String */ } } } while ( mor_in_1 || mor_in_2 ); fclose(&ibuf1); fclose(&ibuf2); putc(CPMEOF, &obuf); fflush(&obuf); fclose(&obuf); printf("%d lines were merged\n", lcount); } /* * compare two strings * ignore case and scan past blanks and punctuation in the comparison * i.e. the beginnings of a lexicographic compare */ TRIAD cmpstr(s, t) char *s, *t; { /* char *s1, *t1; ------ Made global for speed */ /* int i; */ s1 = s; if ( *s1 != 0xff ) /* max string mark */ for ( i = 0; i < skipchars; ++i, ++s1 ) if ( *s1 == '\0' ) break; t1 = t; if ( *t1 != 0xff ) /* max string mark */ for ( i = 0; i < skipchars; ++i, ++t1 ) if ( *t1 == '\0' ) break; if ( *s1 == 0xff || *t1 == 0xff ) return (tolower(*s1) - tolower(*t1)); while ( *s1 && *t1 ) { /* not at the end of either string */ if ( *s1 && ! ( isspace(*s1) || isalpha(*s1) || isdigit(*s1)) ) ++s1; else if ( *t1 && ! ( isspace(*t1) || isalpha(*t1) || isdigit(*t1)) ) ++t1; else if ( *s1 != *t1 ) break; else { /* identical matching non-blanks */ ++s1; ++t1; } } if ( i = (tolower(*s1) - tolower(*t1)) ) /* case independent compare */ return (i); else /* unless they match */ return (*s1 - *t1); } /* * abort with error message */ PROC abort(s) char *s; { printf("%s\n\n", s); puts("Usage:\n\n"); puts("mergelex [-s]\n"); printf("\nLast Revision Date: %s\n", REV_DATE); exit(1); }