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