Home | History | Annotate | Line # | Download | only in dist
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