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