Annotation of src/usr.bin/less/lessecho.c, Revision 1.1.1.2
1.1 millert 1: /*
1.1.1.2 ! shadchin 2: * Copyright (C) 1984-2011 Mark Nudelman
1.1 millert 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:
1.1.1.2 ! shadchin 31: static char *version = "$Revision: 1.14 $";
1.1 millert 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: }