add --version and --help
[platform/upstream/coreutils.git] / src / cat.c
1 /* cat -- concatenate files and print on the standard output.
2    Copyright (C) 1988, 1990, 1991 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17 \f
18 /* Differences from the Unix cat:
19    * Always unbuffered, -u is ignored.
20    * 100 times faster with -v -u.
21    * 20 times faster with -v.
22
23    By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman. */
24
25 #include <stdio.h>
26 #include <getopt.h>
27 #include <sys/types.h>
28 #ifndef _POSIX_SOURCE
29 #include <sys/ioctl.h>
30 #endif
31 #include "system.h"
32 #include "version.h"
33
34 #define max(h,i) ((h) > (i) ? (h) : (i))
35
36 char *stpcpy ();
37 char *xmalloc ();
38 void error ();
39
40 static void cat ();
41 static void next_line_num ();
42 static void simple_cat ();
43
44 /* Name under which this program was invoked.  */
45 char *program_name;
46
47 /* Name of input file.  May be "-".  */
48 static char *infile;
49
50 /* Descriptor on which input file is open.  */
51 static int input_desc;
52
53 /* Descriptor on which output file is open.  Always is 1.  */
54 static int output_desc;
55
56 /* Buffer for line numbers.  */
57 static char line_buf[13] =
58 {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '\t', '\0'};
59
60 /* Position in `line_buf' where printing starts.  This will not change
61    unless the number of lines are more than 999999.  */
62 static char *line_num_print = line_buf + 5;
63
64 /* Position of the first digit in `line_buf'.  */
65 static char *line_num_start = line_buf + 10;
66
67 /* Position of the last digit in `line_buf'.  */
68 static char *line_num_end = line_buf + 10;
69
70 /* Preserves the `cat' function's local `newlines' between invocations.  */
71 static int newlines2 = 0;
72
73 /* Count of non-fatal error conditions.  */
74 static int exit_stat = 0;
75
76 static void
77 usage (reason)
78      char *reason;
79 {
80   if (reason != NULL)
81     fprintf (stderr, "%s: %s\n", program_name, reason);
82
83   fprintf (stderr, "\
84 Usage: %s [-benstuvAET] [--number] [--number-nonblank] [--squeeze-blank]\n\
85        [--show-nonprinting] [--show-ends] [--show-tabs] [--show-all]\n\
86        [--help] [--version] [file...]\n",
87            program_name);
88
89   exit (2);
90 }
91
92 \f
93 void
94 main (argc, argv)
95      int argc;
96      char *argv[];
97 {
98   /* Optimal size of i/o operations of output.  */
99   int outsize;
100
101   /* Optimal size of i/o operations of input.  */
102   int insize;
103
104   /* Pointer to the input buffer.  */
105   unsigned char *inbuf;
106
107   /* Pointer to the output buffer.  */
108   unsigned char *outbuf;
109
110   int c;
111
112   /* Index in argv to processed argument.  */
113   int argind;
114
115   /* Device number of the output (file or whatever).  */
116   int out_dev;
117
118   /* I-node number of the output.  */
119   int out_ino;
120
121   /* Nonzero if the output file should not be the same as any input file. */
122   int check_redirection = 1;
123
124   /* Nonzero if we have ever read standard input. */
125   int have_read_stdin = 0;
126
127   struct stat stat_buf;
128
129   /* Variables that are set according to the specified options.  */
130   int numbers = 0;
131   int numbers_at_empty_lines = 1;
132   int squeeze_empty_lines = 0;
133   int mark_line_ends = 0;
134   int quote = 0;
135   int output_tabs = 1;
136
137 /* If non-zero, call cat, otherwise call simple_cat to do the actual work. */
138   int options = 0;
139
140   /* If non-zero, display usage information and exit.  */
141   static int flag_help;
142
143   /* If non-zero, print the version on standard error.  */
144   static int flag_version;
145
146   static struct option const long_options[] =
147   {
148     {"number-nonblank", no_argument, NULL, 'b'},
149     {"number", no_argument, NULL, 'n'},
150     {"squeeze-blank", no_argument, NULL, 's'},
151     {"show-nonprinting", no_argument, NULL, 'v'},
152     {"show-ends", no_argument, NULL, 'E'},
153     {"show-tabs", no_argument, NULL, 'T'},
154     {"show-all", no_argument, NULL, 'A'},
155     {"help", no_argument, &flag_help, 1},
156     {"version", no_argument, &flag_version, 1},
157     {NULL, 0, NULL, 0}
158   };
159
160   program_name = argv[0];
161
162   /* Parse command line options.  */
163
164   while ((c = getopt_long (argc, argv, "benstuvAET", long_options, (int *) 0))
165          != EOF)
166     {
167       switch (c)
168         {
169         case 0:
170           break;
171
172         case 'b':
173           ++options;
174           numbers = 1;
175           numbers_at_empty_lines = 0;
176           break;
177
178         case 'e':
179           ++options;
180           mark_line_ends = 1;
181           quote = 1;
182           break;
183
184         case 'n':
185           ++options;
186           numbers = 1;
187           break;
188
189         case 's':
190           ++options;
191           squeeze_empty_lines = 1;
192           break;
193
194         case 't':
195           ++options;
196           output_tabs = 0;
197           quote = 1;
198           break;
199
200         case 'u':
201           /* We provide the -u feature unconditionally.  */
202           break;
203
204         case 'v':
205           ++options;
206           quote = 1;
207           break;
208
209         case 'A':
210           ++options;
211           quote = 1;
212           mark_line_ends = 1;
213           output_tabs = 0;
214           break;
215
216         case 'E':
217           ++options;
218           mark_line_ends = 1;
219           break;
220
221         case 'T':
222           ++options;
223           output_tabs = 0;
224           break;
225
226         default:
227           usage ((char *) 0);
228         }
229     }
230
231   if (flag_version)
232     fprintf (stderr, "%s\n", version_string);
233
234   if (flag_help)
235     usage ();
236
237   output_desc = 1;
238
239   /* Get device, i-node number, and optimal blocksize of output.  */
240
241   if (fstat (output_desc, &stat_buf) < 0)
242     error (1, errno, "standard output");
243
244   outsize = ST_BLKSIZE (stat_buf);
245   /* Input file can be output file for non-regular files.
246      fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
247      on others, so the checking should not be done for those types,
248      and to allow things like cat < /dev/tty > /dev/tty, checking
249      is not done for device files either. */
250
251   if (S_ISREG (stat_buf.st_mode))
252     {
253       out_dev = stat_buf.st_dev;
254       out_ino = stat_buf.st_ino;
255     }
256   else
257     check_redirection = 0;
258
259   /* Check if any of the input files are the same as the output file.  */
260
261   /* Main loop.  */
262
263   infile = "-";
264   argind = optind;
265
266   do
267     {
268       if (argind < argc)
269         infile = argv[argind];
270
271       if (infile[0] == '-' && infile[1] == 0)
272         {
273           have_read_stdin = 1;
274           input_desc = 0;
275         }
276       else
277         {
278           input_desc = open (infile, O_RDONLY);
279           if (input_desc < 0)
280             {
281               error (0, errno, "%s", infile);
282               exit_stat = 1;
283               continue;
284             }
285         }
286
287       if (fstat (input_desc, &stat_buf) < 0)
288         {
289           error (0, errno, "%s", infile);
290           exit_stat = 1;
291           goto contin;
292         }
293       insize = ST_BLKSIZE (stat_buf);
294
295       /* Compare the device and i-node numbers of this input file with
296          the corresponding values of the (output file associated with)
297          stdout, and skip this input file if they coincide.  Input
298          files cannot be redirected to themselves.  */
299
300       if (check_redirection
301           && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino)
302         {
303           error (0, 0, "%s: input file is output file", infile);
304           exit_stat = 1;
305           goto contin;
306         }
307
308       /* Select which version of `cat' to use. If any options (more than -u,
309          --version, or --help) were specified, use `cat', otherwise use
310          `simple_cat'.  */
311
312       if (options == 0)
313         {
314           insize = max (insize, outsize);
315           inbuf = (unsigned char *) xmalloc (insize);
316
317           simple_cat (inbuf, insize);
318         }
319       else
320         {
321           inbuf = (unsigned char *) xmalloc (insize + 1);
322
323           /* Why are (OUTSIZE  - 1 + INSIZE * 4 + 13) bytes allocated for
324              the output buffer?
325
326              A test whether output needs to be written is done when the input
327              buffer empties or when a newline appears in the input.  After
328              output is written, at most (OUTSIZE - 1) bytes will remain in the
329              buffer.  Now INSIZE bytes of input is read.  Each input character
330              may grow by a factor of 4 (by the prepending of M-^).  If all
331              characters do, and no newlines appear in this block of input, we
332              will have at most (OUTSIZE - 1 + INSIZE) bytes in the buffer.  If
333              the last character in the preceding block of input was a
334              newline, a line number may be written (according to the given
335              options) as the first thing in the output buffer. (Done after the
336              new input is read, but before processing of the input begins.)  A
337              line number requires seldom more than 13 positions.  */
338
339           outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4 + 13);
340
341           cat (inbuf, insize, outbuf, outsize, quote,
342                output_tabs, numbers, numbers_at_empty_lines, mark_line_ends,
343                squeeze_empty_lines);
344
345           free (outbuf);
346         }
347
348       free (inbuf);
349
350     contin:
351       if (strcmp (infile, "-") && close (input_desc) < 0)
352         {
353           error (0, errno, "%s", infile);
354           exit_stat = 1;
355         }
356     }
357   while (++argind < argc);
358
359   if (have_read_stdin && close (0) < 0)
360     error (1, errno, "-");
361   if (close (1) < 0)
362     error (1, errno, "write error");
363
364   exit (exit_stat);
365 }
366 \f
367 /* Plain cat.  Copies the file behind `input_desc' to the file behind
368    `output_desc'.  */
369
370 static void
371 simple_cat (buf, bufsize)
372      /* Pointer to the buffer, used by reads and writes.  */
373      unsigned char *buf;
374
375      /* Number of characters preferably read or written by each read and write
376         call.  */
377      int bufsize;
378 {
379   /* Actual number of characters read, and therefore written.  */
380   int n_read;
381
382   /* Loop until the end of the file.  */
383
384   for (;;)
385     {
386       /* Read a block of input.  */
387
388       n_read = read (input_desc, buf, bufsize);
389       if (n_read < 0)
390         {
391           error (0, errno, "%s", infile);
392           exit_stat = 1;
393           return;
394         }
395
396       /* End of this file?  */
397
398       if (n_read == 0)
399         break;
400
401       /* Write this block out.  */
402
403       if (write (output_desc, buf, n_read) != n_read)
404         error (1, errno, "write error");
405     }
406 }
407 \f
408 /* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
409    Called if any option more than -u was specified.
410
411    A newline character is always put at the end of the buffer, to make
412    an explicit test for buffer end unnecessary.  */
413
414 static void
415 cat (inbuf, insize, outbuf, outsize, quote,
416      output_tabs, numbers, numbers_at_empty_lines,
417      mark_line_ends, squeeze_empty_lines)
418
419      /* Pointer to the beginning of the input buffer.  */
420      unsigned char *inbuf;
421
422      /* Number of characters read in each read call.  */
423      int insize;
424
425      /* Pointer to the beginning of the output buffer.  */
426      unsigned char *outbuf;
427
428      /* Number of characters written by each write call.  */
429      int outsize;
430
431      /* Variables that have values according to the specified options.  */
432      int quote;
433      int output_tabs;
434      int numbers;
435      int numbers_at_empty_lines;
436      int mark_line_ends;
437      int squeeze_empty_lines;
438 {
439   /* Last character read from the input buffer.  */
440   unsigned char ch;
441
442   /* Pointer to the next character in the input buffer.  */
443   unsigned char *bpin;
444
445   /* Pointer to the first non-valid byte in the input buffer, i.e. the
446      current end of the buffer.  */
447   unsigned char *eob;
448
449   /* Pointer to the position where the next character shall be written.  */
450   unsigned char *bpout;
451
452   /* Number of characters read by the last read call.  */
453   int n_read;
454
455   /* Determines how many consecutive newlines there have been in the
456      input.  0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
457      etc.  Initially 0 to indicate that we are at the beginning of a
458      new line.  The "state" of the procedure is determined by
459      NEWLINES.  */
460   int newlines = newlines2;
461
462 #ifdef FIONREAD
463   /* If nonzero, use the FIONREAD ioctl, as an optimization.
464      (On Ultrix, it is not supported on NFS filesystems.)  */
465   int use_fionread = 1;
466 #endif
467
468   /* The inbuf pointers are initialized so that BPIN > EOB, and thereby input
469      is read immediately.  */
470
471   eob = inbuf;
472   bpin = eob + 1;
473
474   bpout = outbuf;
475
476   for (;;)
477     {
478       do
479         {
480           /* Write if there are at least OUTSIZE bytes in OUTBUF.  */
481
482           if (bpout - outbuf >= outsize)
483             {
484               unsigned char *wp = outbuf;
485               do
486                 {
487                   if (write (output_desc, wp, outsize) != outsize)
488                     error (1, errno, "write error");
489                   wp += outsize;
490                 }
491               while (bpout - wp >= outsize);
492
493               /* Move the remaining bytes to the beginning of the
494                  buffer.  */
495
496               bcopy (wp, outbuf, bpout - wp);
497               bpout = outbuf + (bpout - wp);
498             }
499
500           /* Is INBUF empty?  */
501
502           if (bpin > eob)
503             {
504 #ifdef FIONREAD
505               int n_to_read = 0;
506
507               /* Is there any input to read immediately?
508                  If not, we are about to wait,
509                  so write all buffered output before waiting.  */
510
511               if (use_fionread
512                   && ioctl (input_desc, FIONREAD, &n_to_read) < 0)
513                 {
514                   /* Ultrix returns EOPNOTSUPP on NFS;
515                      HP-UX returns ENOTTY on pipes. */
516                   if (errno == EOPNOTSUPP || errno == ENOTTY)
517                     use_fionread = 0;
518                   else
519                     {
520                       error (0, errno, "cannot do ioctl on `%s'", infile);
521                       exit_stat = 1;
522                       newlines2 = newlines;
523                       return;
524                     }
525                 }
526               if (n_to_read == 0)
527 #endif
528                 {
529                   int n_write = bpout - outbuf;
530
531                   if (write (output_desc, outbuf, n_write) != n_write)
532                     error (1, errno, "write error");
533                   bpout = outbuf;
534                 }
535
536               /* Read more input into INBUF.  */
537
538               n_read = read (input_desc, inbuf, insize);
539               if (n_read < 0)
540                 {
541                   error (0, errno, "%s", infile);
542                   exit_stat = 1;
543                   newlines2 = newlines;
544                   return;
545                 }
546               if (n_read == 0)
547                 {
548                   newlines2 = newlines;
549                   return;
550                 }
551
552               /* Update the pointers and insert a sentinel at the buffer
553                  end.  */
554
555               bpin = inbuf;
556               eob = bpin + n_read;
557               *eob = '\n';
558             }
559           else
560             {
561               /* It was a real (not a sentinel) newline.  */
562
563               /* Was the last line empty?
564                  (i.e. have two or more consecutive newlines been read?)  */
565
566               if (++newlines > 0)
567                 {
568                   /* Are multiple adjacent empty lines to be substituted by
569                      single ditto (-s), and this was the second empty line?  */
570
571                   if (squeeze_empty_lines && newlines >= 2)
572                     {
573                       ch = *bpin++;
574                       continue;
575                     }
576
577                   /* Are line numbers to be written at empty lines (-n)?  */
578
579                   if (numbers && numbers_at_empty_lines)
580                     {
581                       next_line_num ();
582                       bpout = (unsigned char *) stpcpy (bpout, line_num_print);
583                     }
584                 }
585
586               /* Output a currency symbol if requested (-e).  */
587
588               if (mark_line_ends)
589                 *bpout++ = '$';
590
591               /* Output the newline.  */
592
593               *bpout++ = '\n';
594             }
595           ch = *bpin++;
596         }
597       while (ch == '\n');
598
599       /* Are we at the beginning of a line, and line numbers are requested?  */
600
601       if (newlines >= 0 && numbers)
602         {
603           next_line_num ();
604           bpout = (unsigned char *) stpcpy (bpout, line_num_print);
605         }
606
607       /* Here CH cannot contain a newline character.  */
608
609       /* The loops below continue until a newline character is found,
610          which means that the buffer is empty or that a proper newline
611          has been found.  */
612
613       /* If quoting, i.e. at least one of -v, -e, or -t specified,
614          scan for chars that need conversion.  */
615       if (quote)
616         for (;;)
617           {
618             if (ch >= 32)
619               {
620                 if (ch < 127)
621                   *bpout++ = ch;
622                 else if (ch == 127)
623                   *bpout++ = '^',
624                     *bpout++ = '?';
625                 else
626                   {
627                     *bpout++ = 'M',
628                       *bpout++ = '-';
629                     if (ch >= 128 + 32)
630                       if (ch < 128 + 127)
631                         *bpout++ = ch - 128;
632                       else
633                         *bpout++ = '^',
634                           *bpout++ = '?';
635                     else
636                       *bpout++ = '^',
637                         *bpout++ = ch - 128 + 64;
638                   }
639               }
640             else if (ch == '\t' && output_tabs)
641               *bpout++ = '\t';
642             else if (ch == '\n')
643               {
644                 newlines = -1;
645                 break;
646               }
647             else
648               *bpout++ = '^',
649                 *bpout++ = ch + 64;
650
651             ch = *bpin++;
652           }
653       else
654         /* Not quoting, neither of -v, -e, or -t specified.  */
655         for (;;)
656           {
657             if (ch == '\t' && !output_tabs)
658               *bpout++ = '^',
659                 *bpout++ = ch + 64;
660             else if (ch != '\n')
661               *bpout++ = ch;
662             else
663               {
664                 newlines = -1;
665                 break;
666               }
667
668             ch = *bpin++;
669           }
670     }
671 }
672
673 /* Compute the next line number.  */
674
675 static void
676 next_line_num ()
677 {
678   char *endp = line_num_end;
679   do
680     {
681       if ((*endp)++ < '9')
682         return;
683       *endp-- = '0';
684     }
685   while (endp >= line_num_start);
686   *--line_num_start = '1';
687   if (line_num_start < line_num_print)
688     line_num_print--;
689 }