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