lessecho.c revision 128345
160786Sps/*
2128345Stjr * Copyright (C) 1984-2002  Mark Nudelman
360786Sps *
460786Sps * You may distribute under the terms of either the GNU General Public
560786Sps * License or the Less License, as specified in the README file.
660786Sps *
760786Sps * For more information about less, or for information on how to
860786Sps * contact the author, see the README file.
960786Sps */
1060786Sps
1160786Sps
1260786Sps/*
1360786Sps * lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...
1460786Sps * Simply echos its filename arguments on standard output.
1560786Sps * But any argument containing spaces is enclosed in quotes.
1660786Sps *
1760786Sps * -ox	Specifies "x" to be the open quote character.
1860786Sps * -cx	Specifies "x" to be the close quote character.
1960786Sps * -pn	Specifies "n" to be the open quote character, as an integer.
2060786Sps * -dn	Specifies "n" to be the close quote character, as an integer.
21128345Stjr * -mx  Specifies "x" to be a metachar.
22128345Stjr * -nn  Specifies "n" to be a metachar, as an integer.
23128345Stjr * -ex  Specifies "x" to be the escape char for metachars.
24128345Stjr * -fn  Specifies "x" to be the escape char for metachars, as an integer.
2560786Sps * -a	Specifies that all arguments are to be quoted.
2660786Sps *	The default is that only arguments containing spaces are quoted.
2760786Sps */
2860786Sps
2960786Sps#include "less.h"
3060786Sps
31128345Stjrstatic char *version = "$Revision: 1.9 $";
3260786Sps
3360786Spsstatic int quote_all = 0;
3460786Spsstatic char openquote = '"';
3560786Spsstatic char closequote = '"';
36128345Stjrstatic char *meta_escape = "\\";
37128345Stjrstatic char meta_escape_buf[2];
38128345Stjrstatic char metachars[64] = "";
39128345Stjrstatic int num_metachars = 0;
4060786Sps
4160786Sps	static void
4260786Spspr_usage()
4360786Sps{
4460786Sps	fprintf(stderr,
45128345Stjr		"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
4660786Sps}
4760786Sps
4860786Sps	static void
4960786Spspr_version()
5060786Sps{
5160786Sps	char *p;
5260786Sps	char buf[10];
5360786Sps	char *pbuf = buf;
5460786Sps
5560786Sps	for (p = version;  *p != ' ';  p++)
5660786Sps		if (*p == '\0')
5760786Sps			return;
5860786Sps	for (p++;  *p != '$' && *p != ' ' && *p != '\0';  p++)
5960786Sps		*pbuf++ = *p;
6060786Sps	*pbuf = '\0';
6160786Sps	printf("%s\n", buf);
6260786Sps}
6360786Sps
6460786Sps	static void
6560786Spspr_error(s)
6660786Sps	char *s;
6760786Sps{
6860786Sps	fprintf(stderr, "%s\n", s);
6960786Sps	exit(1);
7060786Sps}
7160786Sps
7260786Sps	static long
7360786Spslstrtol(s, radix, pend)
7460786Sps	char *s;
7560786Sps	int radix;
7660786Sps	char **pend;
7760786Sps{
7860786Sps	int v;
7960786Sps	int neg = 0;
8060786Sps	long n = 0;
8160786Sps
8260786Sps	/* Skip leading white space. */
8360786Sps	while (*s == ' ' || *s == '\t')
8460786Sps		s++;
8560786Sps
8660786Sps	/* Check for a leading + or -. */
8760786Sps	if (*s == '-')
8860786Sps	{
8960786Sps		neg = 1;
9060786Sps		s++;
9160786Sps	} else if (*s == '+')
9260786Sps	{
9360786Sps		s++;
9460786Sps	}
9560786Sps
9660786Sps	/* Determine radix if caller does not specify. */
9760786Sps	if (radix == 0)
9860786Sps	{
9960786Sps		radix = 10;
10060786Sps		if (*s == '0')
10160786Sps		{
10260786Sps			switch (*++s)
10360786Sps			{
10460786Sps			case 'x':
10560786Sps				radix = 16;
10660786Sps				s++;
10760786Sps				break;
10860786Sps			default:
10960786Sps				radix = 8;
11060786Sps				break;
11160786Sps			}
11260786Sps		}
11360786Sps	}
11460786Sps
11560786Sps	/* Parse the digits of the number. */
11660786Sps	for (;;)
11760786Sps	{
11860786Sps		if (*s >= '0' && *s <= '9')
11960786Sps			v = *s - '0';
12060786Sps		else if (*s >= 'a' && *s <= 'f')
12160786Sps			v = *s - 'a' + 10;
12260786Sps		else if (*s >= 'A' && *s <= 'F')
12360786Sps			v = *s - 'A' + 10;
12460786Sps		else
12560786Sps			break;
12660786Sps		if (v >= radix)
12760786Sps			break;
12860786Sps		n = n * radix + v;
12960786Sps		s++;
13060786Sps	}
13160786Sps
13260786Sps	if (pend != NULL)
13360786Sps	{
13460786Sps		/* Skip trailing white space. */
13560786Sps		while (*s == ' ' || *s == '\t')
13660786Sps			s++;
13760786Sps		*pend = s;
13860786Sps	}
13960786Sps	if (neg)
14060786Sps		return (-n);
14160786Sps	return (n);
14260786Sps}
14360786Sps
14460786Sps
14560786Sps#if !HAVE_STRCHR
14660786Sps	char *
14760786Spsstrchr(s, c)
14860786Sps	char *s;
14960786Sps	int c;
15060786Sps{
15160786Sps	for ( ;  *s != '\0';  s++)
15260786Sps		if (*s == c)
15360786Sps			return (s);
15460786Sps	if (c == '\0')
15560786Sps		return (s);
15660786Sps	return (NULL);
15760786Sps}
15860786Sps#endif
15960786Sps
16060786Sps	int
16160786Spsmain(argc, argv)
16260786Sps	int argc;
16360786Sps	char *argv[];
16460786Sps{
16560786Sps	char *arg;
16660786Sps	char *s;
16760786Sps	int no_more_options;
16860786Sps
16960786Sps	no_more_options = 0;
17060786Sps	while (--argc > 0)
17160786Sps	{
17260786Sps		arg = *++argv;
17360786Sps		if (*arg != '-' || no_more_options)
17460786Sps			break;
17560786Sps		switch (*++arg)
17660786Sps		{
17760786Sps		case 'a':
17860786Sps			quote_all = 1;
17960786Sps			break;
180128345Stjr		case 'c':
181128345Stjr			closequote = *++arg;
182128345Stjr			break;
183128345Stjr		case 'd':
184128345Stjr			closequote = lstrtol(++arg, 0, &s);
185128345Stjr			if (s == arg)
186128345Stjr				pr_error("Missing number after -d");
187128345Stjr			break;
188128345Stjr		case 'e':
189128345Stjr			if (strcmp(++arg, "-") == 0)
190128345Stjr				meta_escape = "";
191128345Stjr			else
192128345Stjr				meta_escape = arg;
193128345Stjr			break;
194128345Stjr		case 'f':
195128345Stjr			meta_escape_buf[0] = lstrtol(++arg, 0, &s);
196128345Stjr			meta_escape = meta_escape_buf;
197128345Stjr			if (s == arg)
198128345Stjr				pr_error("Missing number after -f");
199128345Stjr			break;
20060786Sps		case 'o':
20160786Sps			openquote = *++arg;
20260786Sps			break;
20360786Sps		case 'p':
20460786Sps			openquote = lstrtol(++arg, 0, &s);
20560786Sps			if (s == arg)
206128345Stjr				pr_error("Missing number after -p");
20760786Sps			break;
208128345Stjr		case 'm':
209128345Stjr			metachars[num_metachars++] = *++arg;
210128345Stjr			metachars[num_metachars] = '\0';
211128345Stjr			break;
212128345Stjr		case 'n':
213128345Stjr			metachars[num_metachars++] = lstrtol(++arg, 0, &s);
21460786Sps			if (s == arg)
215128345Stjr				pr_error("Missing number after -n");
216128345Stjr			metachars[num_metachars] = '\0';
21760786Sps			break;
21860786Sps		case '?':
21960786Sps			pr_usage();
22060786Sps			return (0);
22160786Sps		case '-':
22260786Sps			if (*++arg == '\0')
22360786Sps			{
22460786Sps				no_more_options = 1;
22560786Sps				break;
22660786Sps			}
22760786Sps			if (strcmp(arg, "version") == 0)
22860786Sps			{
22960786Sps				pr_version();
23060786Sps				return (0);
23160786Sps			}
23260786Sps			if (strcmp(arg, "help") == 0)
23360786Sps			{
23460786Sps				pr_usage();
23560786Sps				return (0);
23660786Sps			}
23760786Sps			pr_error("Invalid option after --");
23860786Sps		default:
23960786Sps			pr_error("Invalid option letter");
24060786Sps		}
24160786Sps	}
24260786Sps
24360786Sps	while (argc-- > 0)
24460786Sps	{
245128345Stjr		int has_meta = 0;
24660786Sps		arg = *argv++;
247128345Stjr		for (s = arg;  *s != '\0';  s++)
248128345Stjr		{
249128345Stjr			if (strchr(metachars, *s) != NULL)
250128345Stjr			{
251128345Stjr				has_meta = 1;
252128345Stjr				break;
253128345Stjr			}
254128345Stjr		}
255128345Stjr		if (quote_all || (has_meta && strlen(meta_escape) == 0))
25660786Sps			printf("%c%s%c", openquote, arg, closequote);
257128345Stjr		else
258128345Stjr		{
259128345Stjr			for (s = arg;  *s != '\0';  s++)
260128345Stjr			{
261128345Stjr				if (strchr(metachars, *s) != NULL)
262128345Stjr					printf("%s", meta_escape);
263128345Stjr				printf("%c", *s);
264128345Stjr			}
265128345Stjr		}
26660786Sps		if (argc > 0)
26760786Sps			printf(" ");
26860786Sps		else
26960786Sps			printf("\n");
27060786Sps	}
27160786Sps	return (0);
27260786Sps}
273