summaryrefslogblamecommitdiffstats
path: root/private/sdktools/mrgscomp/mrgscomp.c
blob: 2a773ffe18831c26fe00b385e3817858d5fc9e4a (plain) (tree)





























































































































































































































                                                                              
/*
 * mrgscomp
 *  A merge program for output from slm's SCOMP command.
 *
 *  written 1989 by Jon Parati [jonpa]
 */
#include <stdio.h>
#include <stdlib.h>

#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;
}