Move less-4/ to less/. No need for versioned directories.
[dragonfly.git] / contrib / less / lessecho.c
1 /*
2  * Copyright (C) 1984-2007  Mark Nudelman
3  *
4  * You may distribute under the terms of either the GNU General Public
5  * License or the Less License, as specified in the README file.
6  *
7  * For more information about less, or for information on how to 
8  * contact the author, see the README file.
9  */
10
11
12 /*
13  * lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...
14  * Simply echos its filename arguments on standard output.
15  * But any argument containing spaces is enclosed in quotes.
16  *
17  * -ox  Specifies "x" to be the open quote character.
18  * -cx  Specifies "x" to be the close quote character.
19  * -pn  Specifies "n" to be the open quote character, as an integer.
20  * -dn  Specifies "n" to be the close quote character, as an integer.
21  * -mx  Specifies "x" to be a metachar.
22  * -nn  Specifies "n" to be a metachar, as an integer.
23  * -ex  Specifies "x" to be the escape char for metachars.
24  * -fn  Specifies "x" to be the escape char for metachars, as an integer.
25  * -a   Specifies that all arguments are to be quoted.
26  *      The default is that only arguments containing spaces are quoted.
27  */
28
29 #include "less.h"
30
31 static char *version = "$Revision: 1.11 $";
32
33 static int quote_all = 0;
34 static char openquote = '"';
35 static char closequote = '"';
36 static char *meta_escape = "\\";
37 static char meta_escape_buf[2];
38 static char metachars[64] = "";
39 static int num_metachars = 0;
40
41         static void
42 pr_usage()
43 {
44         fprintf(stderr,
45                 "usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
46 }
47
48         static void
49 pr_version()
50 {
51         char *p;
52         char buf[10];
53         char *pbuf = buf;
54
55         for (p = version;  *p != ' ';  p++)
56                 if (*p == '\0')
57                         return;
58         for (p++;  *p != '$' && *p != ' ' && *p != '\0';  p++)
59                 *pbuf++ = *p;
60         *pbuf = '\0';
61         printf("%s\n", buf);
62 }
63
64         static void
65 pr_error(s)
66         char *s;
67 {
68         fprintf(stderr, "%s\n", s);
69         exit(1);
70 }
71
72         static long
73 lstrtol(s, radix, pend)
74         char *s;
75         int radix;
76         char **pend;
77 {
78         int v;
79         int neg = 0;
80         long n = 0;
81
82         /* Skip leading white space. */
83         while (*s == ' ' || *s == '\t')
84                 s++;
85
86         /* Check for a leading + or -. */
87         if (*s == '-')
88         {
89                 neg = 1;
90                 s++;
91         } else if (*s == '+')
92         {
93                 s++;
94         }
95
96         /* Determine radix if caller does not specify. */
97         if (radix == 0)
98         {
99                 radix = 10;
100                 if (*s == '0')
101                 {
102                         switch (*++s)
103                         {
104                         case 'x':
105                                 radix = 16;
106                                 s++;
107                                 break;
108                         default:
109                                 radix = 8;
110                                 break;
111                         }
112                 }
113         }
114
115         /* Parse the digits of the number. */
116         for (;;)
117         {
118                 if (*s >= '0' && *s <= '9')
119                         v = *s - '0';
120                 else if (*s >= 'a' && *s <= 'f')
121                         v = *s - 'a' + 10;
122                 else if (*s >= 'A' && *s <= 'F')
123                         v = *s - 'A' + 10;
124                 else
125                         break;
126                 if (v >= radix)
127                         break;
128                 n = n * radix + v;
129                 s++;
130         }
131
132         if (pend != NULL)
133         {
134                 /* Skip trailing white space. */
135                 while (*s == ' ' || *s == '\t')
136                         s++;
137                 *pend = s;
138         }
139         if (neg)
140                 return (-n);
141         return (n);
142 }
143
144
145 #if !HAVE_STRCHR
146         char *
147 strchr(s, c)
148         char *s;
149         int c;
150 {
151         for ( ;  *s != '\0';  s++)
152                 if (*s == c)
153                         return (s);
154         if (c == '\0')
155                 return (s);
156         return (NULL);
157 }
158 #endif
159
160         int
161 main(argc, argv)
162         int argc;
163         char *argv[];
164 {
165         char *arg;
166         char *s;
167         int no_more_options;
168
169         no_more_options = 0;
170         while (--argc > 0)
171         {
172                 arg = *++argv;
173                 if (*arg != '-' || no_more_options)
174                         break;
175                 switch (*++arg)
176                 {
177                 case 'a':
178                         quote_all = 1;
179                         break;
180                 case 'c':
181                         closequote = *++arg;
182                         break;
183                 case 'd':
184                         closequote = lstrtol(++arg, 0, &s);
185                         if (s == arg)
186                                 pr_error("Missing number after -d");
187                         break;
188                 case 'e':
189                         if (strcmp(++arg, "-") == 0)
190                                 meta_escape = "";
191                         else
192                                 meta_escape = arg;
193                         break;
194                 case 'f':
195                         meta_escape_buf[0] = lstrtol(++arg, 0, &s);
196                         meta_escape = meta_escape_buf;
197                         if (s == arg)
198                                 pr_error("Missing number after -f");
199                         break;
200                 case 'o':
201                         openquote = *++arg;
202                         break;
203                 case 'p':
204                         openquote = lstrtol(++arg, 0, &s);
205                         if (s == arg)
206                                 pr_error("Missing number after -p");
207                         break;
208                 case 'm':
209                         metachars[num_metachars++] = *++arg;
210                         metachars[num_metachars] = '\0';
211                         break;
212                 case 'n':
213                         metachars[num_metachars++] = lstrtol(++arg, 0, &s);
214                         if (s == arg)
215                                 pr_error("Missing number after -n");
216                         metachars[num_metachars] = '\0';
217                         break;
218                 case '?':
219                         pr_usage();
220                         return (0);
221                 case '-':
222                         if (*++arg == '\0')
223                         {
224                                 no_more_options = 1;
225                                 break;
226                         }
227                         if (strcmp(arg, "version") == 0)
228                         {
229                                 pr_version();
230                                 return (0);
231                         }
232                         if (strcmp(arg, "help") == 0)
233                         {
234                                 pr_usage();
235                                 return (0);
236                         }
237                         pr_error("Invalid option after --");
238                 default:
239                         pr_error("Invalid option letter");
240                 }
241         }
242
243         while (argc-- > 0)
244         {
245                 int has_meta = 0;
246                 arg = *argv++;
247                 for (s = arg;  *s != '\0';  s++)
248                 {
249                         if (strchr(metachars, *s) != NULL)
250                         {
251                                 has_meta = 1;
252                                 break;
253                         }
254                 }
255                 if (quote_all || (has_meta && strlen(meta_escape) == 0))
256                         printf("%c%s%c", openquote, arg, closequote);
257                 else 
258                 {
259                         for (s = arg;  *s != '\0';  s++)
260                         {
261                                 if (strchr(metachars, *s) != NULL)
262                                         printf("%s", meta_escape);
263                                 printf("%c", *s);
264                         }
265                 }
266                 if (argc > 0)
267                         printf(" ");
268                 else
269                         printf("\n");
270         }
271         return (0);
272 }