xref: /NextBSD/contrib/libreadline/examples/rlcat.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /*
2  * rlcat - cat(1) using readline
3  *
4  * usage: rlcat
5  */
6 
7 /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
8 
9    This file is part of the GNU Readline Library, a library for
10    reading lines of text with interactive input and history editing.
11 
12    The GNU Readline Library is free software; you can redistribute it
13    and/or modify it under the terms of the GNU General Public License
14    as published by the Free Software Foundation; either version 2, or
15    (at your option) any later version.
16 
17    The GNU Readline Library is distributed in the hope that it will be
18    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21 
22    The GNU General Public License is often shipped with GNU software, and
23    is generally kept in a file called COPYING or LICENSE.  If you do not
24    have a copy of the license, write to the Free Software Foundation,
25    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
26 
27 #if defined (HAVE_CONFIG_H)
28 #  include <config.h>
29 #endif
30 
31 #ifdef HAVE_UNISTD_H
32 #  include <unistd.h>
33 #endif
34 
35 #include <sys/types.h>
36 #include "posixstat.h"
37 
38 #include <stdio.h>
39 #include <ctype.h>
40 #include <string.h>
41 #include <errno.h>
42 
43 #ifdef HAVE_STDLIB_H
44 #  include <stdlib.h>
45 #else
46 extern void exit();
47 #endif
48 
49 #ifndef errno
50 extern int errno;
51 #endif
52 
53 #if defined (READLINE_LIBRARY)
54 #  include "readline.h"
55 #  include "history.h"
56 #else
57 #  include <readline/readline.h>
58 #  include <readline/history.h>
59 #endif
60 
61 extern int optind;
62 extern char *optarg;
63 
64 static int stdcat();
65 
66 static char *progname;
67 static int vflag;
68 
69 static void
usage()70 usage()
71 {
72   fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
73 }
74 
75 int
main(argc,argv)76 main (argc, argv)
77      int argc;
78      char **argv;
79 {
80   char *temp;
81   int opt, Vflag, Nflag;
82 
83   progname = strrchr(argv[0], '/');
84   if (progname == 0)
85     progname = argv[0];
86   else
87     progname++;
88 
89   vflag = Vflag = Nflag = 0;
90   while ((opt = getopt(argc, argv, "vEVN")) != EOF)
91     {
92       switch (opt)
93 	{
94 	case 'v':
95 	  vflag = 1;
96 	  break;
97 	case 'V':
98 	  Vflag = 1;
99 	  break;
100 	case 'E':
101 	  Vflag = 0;
102 	  break;
103 	case 'N':
104 	  Nflag = 1;
105 	  break;
106 	default:
107 	  usage ();
108 	  exit (2);
109 	}
110     }
111 
112   argc -= optind;
113   argv += optind;
114 
115   if (isatty(0) == 0 || argc || Nflag)
116     return stdcat(argc, argv);
117 
118   rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
119   while (temp = readline (""))
120     {
121       if (*temp)
122         add_history (temp);
123       printf ("%s\n", temp);
124     }
125 
126   return (ferror (stdout));
127 }
128 
129 static int
fcopy(fp)130 fcopy(fp)
131      FILE *fp;
132 {
133   int c;
134   char *x;
135 
136   while ((c = getc(fp)) != EOF)
137     {
138       if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0)
139 	{
140 	  x = rl_untranslate_keyseq (c);
141 	  if (fputs (x, stdout) != 0)
142 	    return 1;
143 	}
144       else if (putchar (c) == EOF)
145         return 1;
146     }
147   return (ferror (stdout));
148 }
149 
150 int
stdcat(argc,argv)151 stdcat (argc, argv)
152      int argc;
153      char **argv;
154 {
155   int  i, fd, r;
156   char *s;
157   FILE *fp;
158 
159   if (argc == 0)
160     return (fcopy(stdin));
161 
162   for (i = 0, r = 1; i < argc; i++)
163     {
164       if (*argv[i] == '-' && argv[i][1] == 0)
165 	fp = stdin;
166       else
167 	{
168 	  fp = fopen (argv[i], "r");
169 	  if (fp == 0)
170 	    {
171 	      fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno));
172 	      continue;
173 	    }
174         }
175       r = fcopy (fp);
176       if (fp != stdin)
177 	fclose(fp);
178     }
179   return r;
180 }
181