lessecho.c revision 128345
1344957Smarcel/*
2344957Smarcel * Copyright (C) 1984-2002  Mark Nudelman
3344957Smarcel *
4344957Smarcel * You may distribute under the terms of either the GNU General Public
5344957Smarcel * License or the Less License, as specified in the README file.
6344957Smarcel *
7344957Smarcel * For more information about less, or for information on how to
8344957Smarcel * contact the author, see the README file.
9344957Smarcel */
10344957Smarcel
11344957Smarcel
12344957Smarcel/*
13344957Smarcel * lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...
14344957Smarcel * Simply echos its filename arguments on standard output.
15344957Smarcel * But any argument containing spaces is enclosed in quotes.
16344957Smarcel *
17344957Smarcel * -ox	Specifies "x" to be the open quote character.
18344957Smarcel * -cx	Specifies "x" to be the close quote character.
19344957Smarcel * -pn	Specifies "n" to be the open quote character, as an integer.
20344957Smarcel * -dn	Specifies "n" to be the close quote character, as an integer.
21344957Smarcel * -mx  Specifies "x" to be a metachar.
22344957Smarcel * -nn  Specifies "n" to be a metachar, as an integer.
23344957Smarcel * -ex  Specifies "x" to be the escape char for metachars.
24344957Smarcel * -fn  Specifies "x" to be the escape char for metachars, as an integer.
25344957Smarcel * -a	Specifies that all arguments are to be quoted.
26344957Smarcel *	The default is that only arguments containing spaces are quoted.
27344957Smarcel */
28344957Smarcel
29344957Smarcel#include "less.h"
30344957Smarcel
31344957Smarcelstatic char *version = "$Revision: 1.9 $";
32344957Smarcel
33344957Smarcelstatic int quote_all = 0;
34344957Smarcelstatic char openquote = '"';
35344957Smarcelstatic char closequote = '"';
36344957Smarcelstatic char *meta_escape = "\\";
37344957Smarcelstatic char meta_escape_buf[2];
38344957Smarcelstatic char metachars[64] = "";
39344957Smarcelstatic int num_metachars = 0;
40344957Smarcel
41344957Smarcel	static void
42344957Smarcelpr_usage()
43344957Smarcel{
44344957Smarcel	fprintf(stderr,
45344957Smarcel		"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
46344957Smarcel}
47344957Smarcel
48344957Smarcel	static void
49344957Smarcelpr_version()
50344957Smarcel{
51344957Smarcel	char *p;
52344957Smarcel	char buf[10];
53344957Smarcel	char *pbuf = buf;
54344957Smarcel
55344957Smarcel	for (p = version;  *p != ' ';  p++)
56344957Smarcel		if (*p == '\0')
57344957Smarcel			return;
58344957Smarcel	for (p++;  *p != '$' && *p != ' ' && *p != '\0';  p++)
59344957Smarcel		*pbuf++ = *p;
60344957Smarcel	*pbuf = '\0';
61344957Smarcel	printf("%s\n", buf);
62344957Smarcel}
63344957Smarcel
64344957Smarcel	static void
65344957Smarcelpr_error(s)
66344957Smarcel	char *s;
67344957Smarcel{
68344957Smarcel	fprintf(stderr, "%s\n", s);
69344957Smarcel	exit(1);
70344957Smarcel}
71344957Smarcel
72344957Smarcel	static long
73344957Smarcellstrtol(s, radix, pend)
74344957Smarcel	char *s;
75344957Smarcel	int radix;
76344957Smarcel	char **pend;
77344957Smarcel{
78344957Smarcel	int v;
79344957Smarcel	int neg = 0;
80344957Smarcel	long n = 0;
81344957Smarcel
82344957Smarcel	/* Skip leading white space. */
83344957Smarcel	while (*s == ' ' || *s == '\t')
84344957Smarcel		s++;
85344957Smarcel
86344957Smarcel	/* Check for a leading + or -. */
87344957Smarcel	if (*s == '-')
88344957Smarcel	{
89344957Smarcel		neg = 1;
90344957Smarcel		s++;
91344957Smarcel	} else if (*s == '+')
92344957Smarcel	{
93344957Smarcel		s++;
94344957Smarcel	}
95344957Smarcel
96344957Smarcel	/* Determine radix if caller does not specify. */
97344957Smarcel	if (radix == 0)
98344957Smarcel	{
99344957Smarcel		radix = 10;
100344957Smarcel		if (*s == '0')
101344957Smarcel		{
102344957Smarcel			switch (*++s)
103344957Smarcel			{
104344957Smarcel			case 'x':
105344957Smarcel				radix = 16;
106344957Smarcel				s++;
107344957Smarcel				break;
108344957Smarcel			default:
109344957Smarcel				radix = 8;
110344957Smarcel				break;
111344957Smarcel			}
112344957Smarcel		}
113344957Smarcel	}
114344957Smarcel
115344957Smarcel	/* Parse the digits of the number. */
116344957Smarcel	for (;;)
117344957Smarcel	{
118344957Smarcel		if (*s >= '0' && *s <= '9')
119344957Smarcel			v = *s - '0';
120344957Smarcel		else if (*s >= 'a' && *s <= 'f')
121344957Smarcel			v = *s - 'a' + 10;
122344957Smarcel		else if (*s >= 'A' && *s <= 'F')
123344957Smarcel			v = *s - 'A' + 10;
124344957Smarcel		else
125344957Smarcel			break;
126344957Smarcel		if (v >= radix)
127344957Smarcel			break;
128344957Smarcel		n = n * radix + v;
129344957Smarcel		s++;
130344957Smarcel	}
131344957Smarcel
132344957Smarcel	if (pend != NULL)
133344957Smarcel	{
134344957Smarcel		/* Skip trailing white space. */
135344957Smarcel		while (*s == ' ' || *s == '\t')
136344957Smarcel			s++;
137344957Smarcel		*pend = s;
138344957Smarcel	}
139344957Smarcel	if (neg)
140344957Smarcel		return (-n);
141344957Smarcel	return (n);
142344957Smarcel}
143344957Smarcel
144344957Smarcel
145344957Smarcel#if !HAVE_STRCHR
146344957Smarcel	char *
147344957Smarcelstrchr(s, c)
148344957Smarcel	char *s;
149344957Smarcel	int c;
150344957Smarcel{
151344957Smarcel	for ( ;  *s != '\0';  s++)
152344957Smarcel		if (*s == c)
153344957Smarcel			return (s);
154344957Smarcel	if (c == '\0')
155344957Smarcel		return (s);
156344957Smarcel	return (NULL);
157344957Smarcel}
158344957Smarcel#endif
159344957Smarcel
160344957Smarcel	int
161344957Smarcelmain(argc, argv)
162344957Smarcel	int argc;
163344957Smarcel	char *argv[];
164344957Smarcel{
165344957Smarcel	char *arg;
166344957Smarcel	char *s;
167344957Smarcel	int no_more_options;
168344957Smarcel
169344957Smarcel	no_more_options = 0;
170344957Smarcel	while (--argc > 0)
171344957Smarcel	{
172344957Smarcel		arg = *++argv;
173344957Smarcel		if (*arg != '-' || no_more_options)
174344957Smarcel			break;
175344957Smarcel		switch (*++arg)
176344957Smarcel		{
177344957Smarcel		case 'a':
178344957Smarcel			quote_all = 1;
179344957Smarcel			break;
180344957Smarcel		case 'c':
181344957Smarcel			closequote = *++arg;
182344957Smarcel			break;
183344957Smarcel		case 'd':
184344957Smarcel			closequote = lstrtol(++arg, 0, &s);
185344957Smarcel			if (s == arg)
186344957Smarcel				pr_error("Missing number after -d");
187344957Smarcel			break;
188344957Smarcel		case 'e':
189344957Smarcel			if (strcmp(++arg, "-") == 0)
190344957Smarcel				meta_escape = "";
191344957Smarcel			else
192344957Smarcel				meta_escape = arg;
193344957Smarcel			break;
194344957Smarcel		case 'f':
195344957Smarcel			meta_escape_buf[0] = lstrtol(++arg, 0, &s);
196344957Smarcel			meta_escape = meta_escape_buf;
197344957Smarcel			if (s == arg)
198344957Smarcel				pr_error("Missing number after -f");
199344957Smarcel			break;
200344957Smarcel		case 'o':
201344957Smarcel			openquote = *++arg;
202344957Smarcel			break;
203344957Smarcel		case 'p':
204344957Smarcel			openquote = lstrtol(++arg, 0, &s);
205344957Smarcel			if (s == arg)
206344957Smarcel				pr_error("Missing number after -p");
207344957Smarcel			break;
208344957Smarcel		case 'm':
209344957Smarcel			metachars[num_metachars++] = *++arg;
210344957Smarcel			metachars[num_metachars] = '\0';
211344957Smarcel			break;
212344957Smarcel		case 'n':
213344957Smarcel			metachars[num_metachars++] = lstrtol(++arg, 0, &s);
214344957Smarcel			if (s == arg)
215344957Smarcel				pr_error("Missing number after -n");
216344957Smarcel			metachars[num_metachars] = '\0';
217344957Smarcel			break;
218344957Smarcel		case '?':
219344957Smarcel			pr_usage();
220344957Smarcel			return (0);
221344957Smarcel		case '-':
222344957Smarcel			if (*++arg == '\0')
223344957Smarcel			{
224344957Smarcel				no_more_options = 1;
225344957Smarcel				break;
226344957Smarcel			}
227344957Smarcel			if (strcmp(arg, "version") == 0)
228344957Smarcel			{
229344957Smarcel				pr_version();
230344957Smarcel				return (0);
231344957Smarcel			}
232344957Smarcel			if (strcmp(arg, "help") == 0)
233344957Smarcel			{
234344957Smarcel				pr_usage();
235344957Smarcel				return (0);
236344957Smarcel			}
237344957Smarcel			pr_error("Invalid option after --");
238344957Smarcel		default:
239344957Smarcel			pr_error("Invalid option letter");
240344957Smarcel		}
241344957Smarcel	}
242344957Smarcel
243344957Smarcel	while (argc-- > 0)
244344957Smarcel	{
245344957Smarcel		int has_meta = 0;
246344957Smarcel		arg = *argv++;
247344957Smarcel		for (s = arg;  *s != '\0';  s++)
248344957Smarcel		{
249344957Smarcel			if (strchr(metachars, *s) != NULL)
250344957Smarcel			{
251344957Smarcel				has_meta = 1;
252344957Smarcel				break;
253344957Smarcel			}
254344957Smarcel		}
255344957Smarcel		if (quote_all || (has_meta && strlen(meta_escape) == 0))
256344957Smarcel			printf("%c%s%c", openquote, arg, closequote);
257344957Smarcel		else
258344957Smarcel		{
259344957Smarcel			for (s = arg;  *s != '\0';  s++)
260344957Smarcel			{
261344957Smarcel				if (strchr(metachars, *s) != NULL)
262344957Smarcel					printf("%s", meta_escape);
263344957Smarcel				printf("%c", *s);
264344957Smarcel			}
265344957Smarcel		}
266344957Smarcel		if (argc > 0)
267344957Smarcel			printf(" ");
268344957Smarcel		else
269344957Smarcel			printf("\n");
270344957Smarcel	}
271344957Smarcel	return (0);
272344957Smarcel}
273344957Smarcel