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