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