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