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