cmp.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* Cmp.c -- compare two files.
  2. Calling syntax:
  3. cmp [ -s ] [ -l ] file1 file2
  4. If file1 is "-", then the standard input will be used.
  5. Effect: Compares the two files. If no differences are detected, then
  6. no error message is printed out and an exit value of 0 is returned.
  7. A message is printed out if the files are different, and 1 is returned.
  8. If there aren't enough arguments, or if there is an io error, then
  9. 2 will be returned.
  10. -s indicates that no messages will be printed out, though the command
  11. will return the appropriate value.
  12. -l indicates that a listing of all the differences will be generated,
  13. instead of the default, which is to quit as soon as the first
  14. difference is found.
  15. Implementation:
  16. Read the argument list, and set the flags.
  17. Open the input files, returning 2 if error.
  18. Loop forever:
  19. {
  20. Read a character from each file.
  21. If the characters are equal
  22. If EOF, and there haven't been any differences thus far, exit 0.
  23. If they're not equal
  24. If EOF, exit 1.
  25. Record that the files are different (difflag=1).
  26. Unless there's the -l option, exit 1.
  27. Increment the current character number. If the character
  28. from the first file is a newline, increment the line number,
  29. and set the character number back to 1.
  30. }
  31. */
  32. #include <stdio.h>
  33. main(argc, argv)
  34. int argc;
  35. char **argv;
  36. {
  37. int i; /* Iteration variable */
  38. int sflag = 0; /* True if the -s option is used */
  39. int lflag = 0; /* True if the -l option is used */
  40. int difflag = 0; /* True if a difference has been detected */
  41. FILE *f1, *f2; /* The input and output files */
  42. char c1, c2; /* Characters being compared */
  43. int lineno = 1; /* Current line */
  44. int charno = 1; /* Current byte */
  45. while ((--argc > 0) && (**(++argv) == '-'))
  46. while (*(++(*argv)) != 0)
  47. switch (**argv)
  48. {
  49. case 'l':
  50. lflag++;
  51. break;
  52. case 's':
  53. sflag++;
  54. lflag--;
  55. break;
  56. default:
  57. fprintf(stderr, "cmp: unknown flag %c.\n", **argv);
  58. return;
  59. }
  60. /* Parse the argument list */
  61. if (argc < 2)
  62. {
  63. fprintf(stderr, "Usage: cmp \[ -s \] \[ -l \] file1 file2\n");
  64. exit(2);
  65. }
  66. /* Parse the first file's name, and open it */
  67. if ((**argv == '-') && ((*argv)[1] == 0))
  68. f1=stdin;
  69. else
  70. if ((f1 = fopen(*argv, "r")) == NULL)
  71. {
  72. if (!sflag)
  73. fprintf(stderr, "cmp: error opening input file %s\n", *argv);
  74. exit(2);
  75. }
  76. argc--;
  77. argv++;
  78. /* Parse the second file's name, and open it */
  79. if ((f2 = fopen(*argv, "r")) == NULL)
  80. {
  81. if (!sflag)
  82. fprintf(stderr, "cmp : error opening input file %s\n", *argv);
  83. exit(2);
  84. }
  85. for (;;)
  86. {
  87. c1=getc(f1);
  88. c2=getc(f2);
  89. /* If the characters are equal, and it's at EOF, return.
  90. Exit code 0 if no differences, otherwise exit code 1. */
  91. if (c1==c2)
  92. {
  93. if (c1 == EOF)
  94. {
  95. fclose(f1);
  96. fclose(f2);
  97. if (difflag)
  98. exit(1);
  99. exit(0);
  100. }
  101. }
  102. else
  103. /* If the characters are different:
  104. If we've reached EOF, return 1.
  105. Else, record that the files are different (difflag=1)
  106. If the -l flag is set, continue. Else, return exit code 1. */
  107. {
  108. if ((c1 == EOF) || (c2 == EOF))
  109. {
  110. fclose(f1);
  111. fclose(f2);
  112. if (c1 == EOF)
  113. argv--;
  114. if (!sflag)
  115. printf("cmp: end of file in %s, line %d, char %d.\n",
  116. *argv, lineno, charno);
  117. exit(1);
  118. }
  119. difflag=1;
  120. if (!sflag)
  121. {
  122. if (lflag)
  123. printf(" %d,%d: %o,%o\n", lineno, charno, c1, c2);
  124. else
  125. printf("cmp: difference at line %d, char %d, %o, %o\n",
  126. lineno, charno, c1, c2);
  127. }
  128. if (!(lflag))
  129. {
  130. fclose(f1);
  131. fclose(f2);
  132. exit(1);
  133. }
  134. }
  135. /* Increment the character number. If the character is a newline,
  136. then reset the character number and increment the line number */
  137. charno++;
  138. if (c1 == '\n')
  139. {
  140. lineno++;
  141. charno=1;
  142. }
  143. }
  144. }