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