/* Cmp.c -- compare two files.

   Calling syntax:
     cmp [ -s ] [ -l ] file1 file2

     If file1 is "-", then the standard input will be used.

   Effect: Compares the two files.  If no differences are detected, then 
	no error message is printed out and an exit value of 0 is returned.
     A message is printed out if the files are different, and 1 is returned.
     If there aren't enough arguments, or if there is an io error, then
     2 will be returned.

     -s indicates that no messages will be printed out, though the command
	   will return the appropriate value.
     -l indicates that a listing of all the differences will be generated,
        instead of the default, which is to quit as soon as the first
	   difference is found.

    Implementation:    
	  Read the argument list, and set the flags.
	  Open the input files, returning 2 if error.
	  Loop forever:
		{
		Read a character from each file.
		If the characters are equal
		   If EOF, and there haven't been any differences thus far, exit 0.
          If they're not equal
		   If EOF, exit 1.
		   Record that the files are different (difflag=1).
		   Unless there's the -l option, exit 1.

	     Increment the current character number.  If the character
	        from the first file is a newline, increment the line number,
		   and set the character number back to 1.          
		}
*/ 
	
#include <stdio.h>

main(argc, argv)
   int argc;
   char **argv;
   {

   int i;				/* Iteration variable */
   int sflag = 0;		/* True if the -s option is used */
   int lflag = 0;		/* True if the -l option is used */
   int difflag = 0; 	/* True if a difference has been detected */
   FILE *f1, *f2;		/* The input and output files */
   char c1, c2;          /* Characters being compared */
   int lineno = 1;         /* Current line */
   int charno = 1;         /* Current byte */


   while ((--argc > 0) && (**(++argv) == '-'))
	 while (*(++(*argv)) != 0)
	   switch (**argv)
	      {
		 case 'l':
		    lflag++;
		    break;
		 case 's':
		    sflag++;
		    lflag--;
		    break;
		 default:
			fprintf(stderr, "cmp: unknown flag %c.\n", **argv);
			return;
		 }



   /* Parse the argument list */
   if (argc < 	2)
      {
      fprintf(stderr, "Usage: cmp \[ -s \] \[ -l \] file1 file2\n");
      exit(2);
      }



   /* Parse the first file's name, and open it */
   if ((**argv == '-') && ((*argv)[1] == 0))
      f1=stdin;
   else
	if ((f1 = fopen(*argv, "r")) == NULL)
        {
	   if (!sflag)
	      fprintf(stderr, "cmp: error opening input file %s\n", *argv);
	   exit(2);
        }
   argc--;
   argv++;

   /* Parse the second file's name, and open it */
   if ((f2 = fopen(*argv, "r")) == NULL)
      {
	 if (!sflag)
	    fprintf(stderr, "cmp : error opening input file %s\n", *argv);
	 exit(2);
	 }

   for (;;)
      {
	 c1=getc(f1);
	 c2=getc(f2);

	 /* If the characters are equal, and it's at EOF, return.
	    Exit code 0 if no differences, otherwise exit code 1.  */

	 if (c1==c2)
	    {
         if (c1 == EOF)
	       {
		  fclose(f1);
	 	  fclose(f2);
		  if (difflag)
		     exit(1);
		  exit(0);
		  }
	    }

	 else
	    /* If the characters are different:
		     If we've reached EOF, return 1.
			Else, record that the files are different (difflag=1)
			If the -l flag is set, continue.  Else, return exit code 1.	*/

	    {
         if ((c1 == EOF) || (c2 == EOF))
	       {
		  fclose(f1);
		  fclose(f2);

  	       if (c1 == EOF)
		     argv--;
            if (!sflag)
		     printf("cmp: end of file in %s, line %d, char %d.\n",
			         *argv, lineno, charno);
		  exit(1);	  
		  }

         difflag=1;
	    if (!sflag)
		  {
		  if (lflag)
			printf("	%d,%d: %o,%o\n", lineno, charno, c1, c2);
		  else
	          printf("cmp: difference at line %d, char %d, %o, %o\n",
				    lineno, charno, c1, c2);
            }
		
         if (!(lflag))
		  {
		  fclose(f1);
		  fclose(f2);
		  exit(1);
		  }
	    }

	 /* Increment the character number.  If the character is a newline,
	    then reset the character number and increment the line number */

      charno++;
	 if (c1 == '\n')
	    {
	    lineno++;
	    charno=1;
	    }
      }
   }





     