/* * mrgscomp * A merge program for output from slm's SCOMP command. * * written 1989 by Jon Parati [jonpa] */ #include #include #define BOOL int #define FALSE 0 #define TRUE !FALSE char szDiffLine[255]; char szTmpBuff[255]; char szSepLine[] = "------------------------------------------------------\n"; FILE *pfInFile, *pfOut, *pfDiff; BOOL EchoOrEatTillLine( int usStart, int *pusLine, FILE *pfInFile, FILE *pfOut, BOOL fEcho ); void _CRTAPI1 main( int cArgs, char *szArg[] ); void _CRTAPI1 main( cArgs, szArg ) int cArgs; char *szArg[]; { int usStart; int usStop; int usLine = 1; char chCmd; int cScn; /* * parse the command line */ pfOut = stdout; pfDiff = stdin; switch( cArgs ) { case 4: pfOut = fopen( szArg[3], "w" ); if( pfOut == NULL ) { fprintf( stderr, "mrgscomp: can not open output file '%s'\n", szArg[3] ); exit(1); } /* fall through to next case */ case 3: pfDiff = fopen( szArg[2], "r" ); if( pfDiff == NULL ) { fprintf( stderr, "mrgscomp: can not open diff file '%s'\n", szArg[2] ); exit(1); } /* fall through to next case */ case 2: pfInFile = fopen( szArg[1], "r" ); if( pfInFile == NULL ) { fprintf( stderr, "mrgscomp: can not open input file '%s'\n", szArg[1] ); exit(1); } break; default: /* * Syntax error */ fprintf( stderr, "usage: mrgscomp in_file [scomp_file [out_file]]\n\n" "where\n" " in_file is the new version of the file\n" " scomp_file is the output of 'scomp file' or" " 'diff old new'\n" " out_file is the filename to write merged file to\n" ); exit(1); } /* * for each line in the diff file, * read the line in and decode it from RIGHT to LEFT * and reverse the commands so we can recreate the org * file from the new version. * * For more information on what this loop is doing, see * the third sentence in the second paragraph of the * Xenix 'man' page for 'diff'. * */ while( fgets( szDiffLine, sizeof( szDiffLine ), pfDiff ) != NULL ) { /* * parse the line */ if( (cScn = sscanf( szDiffLine, "%*i,%*i%c%i,%i", &chCmd, &usStart, &usStop)) < 2 ) { /* * Not a '# cmd #[,#]' see if it is a '#,# cmd #[,#]' */ if( (cScn = sscanf( szDiffLine, "%*i%c%i,%i", &chCmd, &usStart, &usStop )) < 2 ) { /* * must be a '<' '---' or '>' line * so echo it and then get the next line */ fputs( szDiffLine, pfOut ); continue; } } /* check if one line command */ if( cScn == 2 ) { usStop = usStart; } /* convert inclusive inclusive address to inclusive exclusive */ usStop++; /* * Now act on the command */ switch( chCmd ) { case 'a': /* * Remove the lines that were [a]dded */ EchoOrEatTillLine( usStart, &usLine, pfInFile, pfOut, TRUE ); EchoOrEatTillLine( usStop, &usLine, pfInFile, pfOut, FALSE ); break; case 'd': /* * Replace lines that were [d]eleted */ EchoOrEatTillLine(usStart + 1, &usLine, pfInFile,pfOut,TRUE); break; case 'c': /* * Revert lines that were changed */ EchoOrEatTillLine( usStart, &usLine, pfInFile, pfOut, TRUE ); EchoOrEatTillLine( usStop, &usLine, pfInFile, pfOut, FALSE ); break; default: /* * Don't know what kind of line this is so just * echo it back out and continue */ break; } fputs( szDiffLine, pfOut ); } /* Echo the rest of the line out */ fputs( szSepLine, pfOut ); while( fgets( szTmpBuff, sizeof( szTmpBuff ), pfInFile ) != NULL ) fputs( szTmpBuff, pfOut ); /* Close all the files and exit */ fclose( pfOut ); fclose( pfInFile ); fclose( pfDiff ); exit(0); } BOOL EchoOrEatTillLine( usStart, pusLine, pfInFile, pfOut, fEcho ) int usStart; int *pusLine; FILE *pfInFile; FILE *pfOut; BOOL fEcho; { if( fEcho ) fputs( szSepLine, pfOut ); while( *pusLine < usStart ) { if( fgets( szTmpBuff, sizeof( szTmpBuff ), pfInFile ) == NULL ) return FALSE; (*pusLine)++; if( fEcho ) fputs( szTmpBuff, pfOut ); } if( fEcho ) fputs( szSepLine, pfOut ); return TRUE; }