]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/less/lessecho.c
Merge clang trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / less / lessecho.c
1 /*
2  * Copyright (C) 1984-2015  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(void)
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(void)
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(char *s)
65 {
66         fprintf(stderr, "%s\n", s);
67         exit(1);
68 }
69
70         static long
71 lstrtol(char *s, int radix, char **pend)
72 {
73         int v;
74         int neg = 0;
75         long n = 0;
76
77         /* Skip leading white space. */
78         while (*s == ' ' || *s == '\t')
79                 s++;
80
81         /* Check for a leading + or -. */
82         if (*s == '-')
83         {
84                 neg = 1;
85                 s++;
86         } else if (*s == '+')
87         {
88                 s++;
89         }
90
91         /* Determine radix if caller does not specify. */
92         if (radix == 0)
93         {
94                 radix = 10;
95                 if (*s == '0')
96                 {
97                         switch (*++s)
98                         {
99                         case 'x':
100                                 radix = 16;
101                                 s++;
102                                 break;
103                         default:
104                                 radix = 8;
105                                 break;
106                         }
107                 }
108         }
109
110         /* Parse the digits of the number. */
111         for (;;)
112         {
113                 if (*s >= '0' && *s <= '9')
114                         v = *s - '0';
115                 else if (*s >= 'a' && *s <= 'f')
116                         v = *s - 'a' + 10;
117                 else if (*s >= 'A' && *s <= 'F')
118                         v = *s - 'A' + 10;
119                 else
120                         break;
121                 if (v >= radix)
122                         break;
123                 n = n * radix + v;
124                 s++;
125         }
126
127         if (pend != NULL)
128         {
129                 /* Skip trailing white space. */
130                 while (*s == ' ' || *s == '\t')
131                         s++;
132                 *pend = s;
133         }
134         if (neg)
135                 return (-n);
136         return (n);
137 }
138
139
140 #if !HAVE_STRCHR
141         char *
142 strchr(s, c)
143         char *s;
144         int c;
145 {
146         for ( ;  *s != '\0';  s++)
147                 if (*s == c)
148                         return (s);
149         if (c == '\0')
150                 return (s);
151         return (NULL);
152 }
153 #endif
154
155         int
156 main(argc, argv)
157         int argc;
158         char *argv[];
159 {
160         char *arg;
161         char *s;
162         int no_more_options;
163
164         no_more_options = 0;
165         while (--argc > 0)
166         {
167                 arg = *++argv;
168                 if (*arg != '-' || no_more_options)
169                         break;
170                 switch (*++arg)
171                 {
172                 case 'a':
173                         quote_all = 1;
174                         break;
175                 case 'c':
176                         closequote = *++arg;
177                         break;
178                 case 'd':
179                         closequote = lstrtol(++arg, 0, &s);
180                         if (s == arg)
181                                 pr_error("Missing number after -d");
182                         break;
183                 case 'e':
184                         if (strcmp(++arg, "-") == 0)
185                                 meta_escape = "";
186                         else
187                                 meta_escape = arg;
188                         break;
189                 case 'f':
190                         meta_escape_buf[0] = lstrtol(++arg, 0, &s);
191                         meta_escape = meta_escape_buf;
192                         if (s == arg)
193                                 pr_error("Missing number after -f");
194                         break;
195                 case 'o':
196                         openquote = *++arg;
197                         break;
198                 case 'p':
199                         openquote = lstrtol(++arg, 0, &s);
200                         if (s == arg)
201                                 pr_error("Missing number after -p");
202                         break;
203                 case 'm':
204                         metachars[num_metachars++] = *++arg;
205                         metachars[num_metachars] = '\0';
206                         break;
207                 case 'n':
208                         metachars[num_metachars++] = lstrtol(++arg, 0, &s);
209                         if (s == arg)
210                                 pr_error("Missing number after -n");
211                         metachars[num_metachars] = '\0';
212                         break;
213                 case '?':
214                         pr_usage();
215                         return (0);
216                 case '-':
217                         if (*++arg == '\0')
218                         {
219                                 no_more_options = 1;
220                                 break;
221                         }
222                         if (strcmp(arg, "version") == 0)
223                         {
224                                 pr_version();
225                                 return (0);
226                         }
227                         if (strcmp(arg, "help") == 0)
228                         {
229                                 pr_usage();
230                                 return (0);
231                         }
232                         pr_error("Invalid option after --");
233                 default:
234                         pr_error("Invalid option letter");
235                 }
236         }
237
238         while (argc-- > 0)
239         {
240                 int has_meta = 0;
241                 arg = *argv++;
242                 for (s = arg;  *s != '\0';  s++)
243                 {
244                         if (strchr(metachars, *s) != NULL)
245                         {
246                                 has_meta = 1;
247                                 break;
248                         }
249                 }
250                 if (quote_all || (has_meta && strlen(meta_escape) == 0))
251                         printf("%c%s%c", openquote, arg, closequote);
252                 else 
253                 {
254                         for (s = arg;  *s != '\0';  s++)
255                         {
256                                 if (strchr(metachars, *s) != NULL)
257                                         printf("%s", meta_escape);
258                                 printf("%c", *s);
259                         }
260                 }
261                 if (argc > 0)
262                         printf(" ");
263                 else
264                         printf("\n");
265         }
266         return (0);
267 }