Home | History | Annotate | Line # | Download | only in dist
lessecho.c revision 1.3.2.1
      1 /*	$NetBSD: lessecho.c,v 1.3.2.1 2014/05/22 15:45:43 yamt 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.3";
     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 pr_usage __P((void));
     43 static void pr_version __P((void));
     44 static void pr_error __P((char *));
     45 static long lstrtol __P((char *, int, char **));
     46 
     47 	static void
     48 pr_usage()
     49 {
     50 	fprintf(stderr,
     51 		"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
     52 }
     53 
     54 	static void
     55 pr_version()
     56 {
     57 	char *p;
     58 	char buf[10];
     59 	char *pbuf = buf;
     60 
     61 	for (p = version;  *p != ' ';  p++)
     62 		if (*p == '\0')
     63 			return;
     64 	for (p++;  *p != '$' && *p != ' ' && *p != '\0';  p++)
     65 		*pbuf++ = *p;
     66 	*pbuf = '\0';
     67 	printf("%s\n", buf);
     68 }
     69 
     70 	static void
     71 pr_error(s)
     72 	char *s;
     73 {
     74 	fprintf(stderr, "%s\n", s);
     75 	exit(1);
     76 }
     77 
     78 	static long
     79 lstrtol(s, radix, pend)
     80 	char *s;
     81 	int radix;
     82 	char **pend;
     83 {
     84 	int v;
     85 	int neg = 0;
     86 	long n = 0;
     87 
     88 	/* Skip leading white space. */
     89 	while (*s == ' ' || *s == '\t')
     90 		s++;
     91 
     92 	/* Check for a leading + or -. */
     93 	if (*s == '-')
     94 	{
     95 		neg = 1;
     96 		s++;
     97 	} else if (*s == '+')
     98 	{
     99 		s++;
    100 	}
    101 
    102 	/* Determine radix if caller does not specify. */
    103 	if (radix == 0)
    104 	{
    105 		radix = 10;
    106 		if (*s == '0')
    107 		{
    108 			switch (*++s)
    109 			{
    110 			case 'x':
    111 				radix = 16;
    112 				s++;
    113 				break;
    114 			default:
    115 				radix = 8;
    116 				break;
    117 			}
    118 		}
    119 	}
    120 
    121 	/* Parse the digits of the number. */
    122 	for (;;)
    123 	{
    124 		if (*s >= '0' && *s <= '9')
    125 			v = *s - '0';
    126 		else if (*s >= 'a' && *s <= 'f')
    127 			v = *s - 'a' + 10;
    128 		else if (*s >= 'A' && *s <= 'F')
    129 			v = *s - 'A' + 10;
    130 		else
    131 			break;
    132 		if (v >= radix)
    133 			break;
    134 		n = n * radix + v;
    135 		s++;
    136 	}
    137 
    138 	if (pend != NULL)
    139 	{
    140 		/* Skip trailing white space. */
    141 		while (*s == ' ' || *s == '\t')
    142 			s++;
    143 		*pend = s;
    144 	}
    145 	if (neg)
    146 		return (-n);
    147 	return (n);
    148 }
    149 
    150 
    151 #if !HAVE_STRCHR
    152 	char *
    153 strchr(s, c)
    154 	char *s;
    155 	int c;
    156 {
    157 	for ( ;  *s != '\0';  s++)
    158 		if (*s == c)
    159 			return (s);
    160 	if (c == '\0')
    161 		return (s);
    162 	return (NULL);
    163 }
    164 #endif
    165 
    166 	int
    167 main(argc, argv)
    168 	int argc;
    169 	char *argv[];
    170 {
    171 	char *arg;
    172 	char *s;
    173 	int no_more_options;
    174 
    175 	no_more_options = 0;
    176 	while (--argc > 0)
    177 	{
    178 		arg = *++argv;
    179 		if (*arg != '-' || no_more_options)
    180 			break;
    181 		switch (*++arg)
    182 		{
    183 		case 'a':
    184 			quote_all = 1;
    185 			break;
    186 		case 'c':
    187 			closequote = *++arg;
    188 			break;
    189 		case 'd':
    190 			closequote = lstrtol(++arg, 0, &s);
    191 			if (s == arg)
    192 				pr_error("Missing number after -d");
    193 			break;
    194 		case 'e':
    195 			if (strcmp(++arg, "-") == 0)
    196 				meta_escape = "";
    197 			else
    198 				meta_escape = arg;
    199 			break;
    200 		case 'f':
    201 			meta_escape_buf[0] = lstrtol(++arg, 0, &s);
    202 			meta_escape = meta_escape_buf;
    203 			if (s == arg)
    204 				pr_error("Missing number after -f");
    205 			break;
    206 		case 'o':
    207 			openquote = *++arg;
    208 			break;
    209 		case 'p':
    210 			openquote = lstrtol(++arg, 0, &s);
    211 			if (s == arg)
    212 				pr_error("Missing number after -p");
    213 			break;
    214 		case 'm':
    215 			metachars[num_metachars++] = *++arg;
    216 			metachars[num_metachars] = '\0';
    217 			break;
    218 		case 'n':
    219 			metachars[num_metachars++] = lstrtol(++arg, 0, &s);
    220 			if (s == arg)
    221 				pr_error("Missing number after -n");
    222 			metachars[num_metachars] = '\0';
    223 			break;
    224 		case '?':
    225 			pr_usage();
    226 			return (0);
    227 		case '-':
    228 			if (*++arg == '\0')
    229 			{
    230 				no_more_options = 1;
    231 				break;
    232 			}
    233 			if (strcmp(arg, "version") == 0)
    234 			{
    235 				pr_version();
    236 				return (0);
    237 			}
    238 			if (strcmp(arg, "help") == 0)
    239 			{
    240 				pr_usage();
    241 				return (0);
    242 			}
    243 			pr_error("Invalid option after --");
    244 		default:
    245 			pr_error("Invalid option letter");
    246 		}
    247 	}
    248 
    249 	while (argc-- > 0)
    250 	{
    251 		int has_meta = 0;
    252 		arg = *argv++;
    253 		for (s = arg;  *s != '\0';  s++)
    254 		{
    255 			if (strchr(metachars, *s) != NULL)
    256 			{
    257 				has_meta = 1;
    258 				break;
    259 			}
    260 		}
    261 		if (quote_all || (has_meta && strlen(meta_escape) == 0))
    262 			printf("%c%s%c", openquote, arg, closequote);
    263 		else
    264 		{
    265 			for (s = arg;  *s != '\0';  s++)
    266 			{
    267 				if (strchr(metachars, *s) != NULL)
    268 					printf("%s", meta_escape);
    269 				printf("%c", *s);
    270 			}
    271 		}
    272 		if (argc > 0)
    273 			printf(" ");
    274 		else
    275 			printf("\n");
    276 	}
    277 	return (0);
    278 }
    279