Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/echogs.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1995-2004 artofcode LLC. All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: echogs.c,v 1.7 2004/01/07 19:50:35 giles Exp $ */
18
/* 'echo'-like utility */
19
 
20
#include "stdpre.h"
21
#include <stdio.h>
22
#include <stdlib.h>
23
 
24
#if defined(__sun__) && !defined(const)
25
/* Apparently, there are archaic Sun platforms which don't include
26
 * prototypes for fputc/fputs in stdio.h. The following prototype can
27
 * cause type mismatches if const has been defined (usually with
28
 * -Dconst=), so it's only included if const is undefined.
29
 */
30
extern int fputc(int, FILE *), fputs(const char *, FILE *);
31
#endif
32
 
33
/* Some systems have time_t in sys/types.h rather than time.h. */
34
#include <sys/types.h>
35
#include <ctype.h>
36
#include <string.h>
37
#include <time.h>		/* for ctime */
38
 
39
/*
40
 * This program exists solely to get around omissions, problems, and
41
 * incompatibilities in various shells and utility environments.
42
 * Don't count on it staying the same from one release to another!
43
 */
44
 
45
/*
46
 * Usage:
47
 echogs [-e .extn] [-(w|a)[b][-] file] [-h] [-n]
48
 (-b|-B | -d|-D | -f|-F | -x hexstring | -(l|q|Q) string | -(l|q|Q)string |
49
 -s | -u string | -i | -r file | -R file | -X)*
50
 [-] string*
51
 * Echoes string(s), or the binary equivalent of hexstring(s).
52
 * If -w, writes to file; if -a, appends to file; if neither,
53
 *   writes to stdout.  -wb and -ab open the file in binary mode.
54
 *   -w and -a search forward for the next argument that is not a switch.
55
 *   An appended - means the same as - alone, taking effect after the file
56
 *   argument.
57
 * -e specifies an extension to be added to the file name.
58
 * If -h, write the output in hex instead of literally.
59
 * If -n, does not append a newline to the output.
60
 * -b or -B means insert the base part (minus directories) of the file name
61
 *   passed as the argument of -w or -a.
62
 * -d or -D means insert the date and time.
63
 * -f or -F means insert the file name passed as the argument of -w or -a.
64
 * -q means write the next string literally.
65
 * -l or -Q means the same as -q followed by -s.
66
 * -s means write a space.
67
 * -u means convert the next string to upper case.
68
 * -i means read from stdin, treating each line as an argument.
69
 * -r means read from a named file in the same way.
70
 * -R means copy a named file with no interpretation
71
 *   (but convert to hex if -h is in effect).
72
 * -X means treat any following literals as hex rather than string data.
73
 * - or -+ alone means treat the rest of the line as literal data,
74
 *   even if the first string begins with a -.
75
 * -+<letter> is equivalent to -<Letter>, i.e., it upper-cases the letter.
76
 * Inserts spaces automatically between the trailing strings,
77
 * but nowhere else; in particular,
78
 echogs -q a b
79
 * writes 'ab', in contrast to
80
 echogs -q a -s b
81
 * which writes 'a b'.
82
 */
83
 
84
static int hputc(int, FILE *), hputs(const char *, FILE *);
85
 
86
int
87
main(int argc, char *argv[])
88
{
89
    FILE *out = stdout;
90
    /*
91
     * The initialization in = 0 is unnecessary: in is only referenced if
92
     * interact = 1, in which case in has always been initialized.
93
     * We initialize in = 0 solely to pacify stupid compilers.
94
     */
95
    FILE *in = 0;
96
    const char *extn = "";
97
    char fmode[4];
98
#define FNSIZE 100
99
    char *fnparam;
100
    char fname[FNSIZE];
101
    int newline = 1;
102
    int interact = 0;
103
    int (*eputc)(int, FILE *) = fputc;
104
    int (*eputs)(const char *, FILE *) = fputs;
105
#define LINESIZE 1000
106
    char line[LINESIZE];
107
    char sw = 0, sp = 0, hexx = 0;
108
    char **argp = argv + 1;
109
    int nargs = argc - 1;
110
 
111
    if (nargs > 0 && !strcmp(*argp, "-e")) {
112
	if (nargs < 2)
113
	    return 1;
114
	extn = argp[1];
115
	argp += 2, nargs -= 2;
116
    }
117
    if (nargs > 0 && (*argp)[0] == '-' &&
118
	((*argp)[1] == 'w' || (*argp)[1] == 'a')
119
	) {
120
	size_t len = strlen(*argp);
121
	int i;
122
 
123
	if (len > 4)
124
	    return 1;
125
	for (i = 1; i < nargs; i++)
126
	    if (argp[i][0] != '-')
127
		break;
128
	if (i == nargs)
129
	    return 1;
130
	fnparam = argp[i];
131
	strcpy(fmode, *argp + 1);
132
	strcpy(fname, fnparam);
133
	strcat(fname, extn);
134
	if (fmode[len - 2] == '-') {
135
	    /*
136
	     * The referents of argp are actually const, but they can't be
137
	     * declared that way, so we have to make a writable constant.
138
	     */
139
	    static char dash[2] = { '-', 0 };
140
 
141
	    fmode[len - 2] = 0;
142
	    argp[i] = dash;
143
	    argp++, nargs--;
144
	} else {
145
	    for (; i > 1; i--)
146
		argp[i] = argp[i - 1];
147
	    argp += 2, nargs -= 2;
148
	}
149
    } else
150
	strcpy(fname, "");
151
    if (nargs > 0 && !strcmp(*argp, "-h")) {
152
	eputc = hputc, eputs = hputs;
153
	argp++, nargs--;
154
    }
155
    if (nargs > 0 && !strcmp(*argp, "-n")) {
156
	newline = 0;
157
	argp++, nargs--;
158
    }
159
    if (strlen(fname) != 0) {
160
	out = fopen(fname, fmode);
161
	if (out == 0)
162
	    return 1;
163
    }
164
    while (1) {
165
	char *arg;
166
 
167
	if (interact) {
168
	    if (fgets(line, LINESIZE, in) == NULL) {
169
		interact = 0;
170
		if (in != stdin)
171
		    fclose(in);
172
		continue;
173
	    }
174
	    /* Remove the terminating \n. */
175
	    line[strlen(line) - 1] = 0;
176
	    arg = line;
177
	} else {
178
	    if (nargs == 0)
179
		break;
180
	    arg = *argp;
181
	    argp++, nargs--;
182
	}
183
	if (sw == 0 && arg[0] == '-') {
184
	    char chr = arg[1];
185
 
186
	    sp = 0;
187
	  swc:switch (chr) {
188
		case 'l':	/* literal string, then -s */
189
		    chr = 'Q';
190
		    /* falls through */
191
		case 'q':	/* literal string */
192
		case 'Q':	/* literal string, then -s */
193
		    if (arg[2] != 0) {
194
			(*eputs) (arg + 2, out);
195
			if (chr == 'Q')
196
			    (*eputc) (' ', out);
197
			break;
198
		    }
199
		    /* falls through */
200
		case 'r':	/* read from a file */
201
		case 'R':
202
		case 'u':	/* upper-case string */
203
		case 'x':	/* hex string */
204
		    sw = chr;
205
		    break;
206
		case 's':	/* write a space */
207
		    (*eputc) (' ', out);
208
		    break;
209
		case 'i':	/* read interactively */
210
		    interact = 1;
211
		    in = stdin;
212
		    break;
213
		case 'b':	/* insert base file name */
214
		case 'B':
215
		    arg = fnparam + strlen(fnparam);
216
		    while (arg > fnparam &&
217
			   (isalnum(arg[-1]) || arg[-1] == '_'))
218
			--arg;
219
		    (*eputs) (arg, out);
220
		    break;
221
		case 'd':	/* insert date/time */
222
		case 'D':
223
		    {
224
			time_t t;
225
			char str[26];
226
 
227
			time(&t);
228
			strcpy(str, ctime(&t));
229
			str[24] = 0;	/* remove \n */
230
			(*eputs) (str, out);
231
		    } break;
232
		case 'f':	/* insert file name */
233
		case 'F':
234
		    (*eputs) (fnparam, out);
235
		    break;
236
		case 'X':	/* treat literals as hex */
237
		    hexx = 1;
238
		    break;
239
		case '+':	/* upper-case command */
240
		    if (arg[1]) {
241
			++arg;
242
			chr = toupper(arg[1]);
243
			goto swc;
244
		    }
245
		    /* falls through */
246
		case 0:		/* just '-' */
247
		    sw = '-';
248
		    break;
249
	    }
250
	} else
251
	    switch (sw) {
252
		case 0:
253
		case '-':
254
		    if (hexx)
255
			goto xx;
256
		    if (sp)
257
			(*eputc) (' ', out);
258
		    (*eputs) (arg, out);
259
		    sp = 1;
260
		    break;
261
		case 'q':
262
		    sw = 0;
263
		    (*eputs) (arg, out);
264
		    break;
265
		case 'Q':
266
		    sw = 0;
267
		    (*eputs) (arg, out);
268
		    (*eputc) (' ', out);
269
		    break;
270
		case 'r':
271
		    sw = 0;
272
		    in = fopen(arg, "r");
273
		    if (in == NULL)
274
			exit(exit_FAILED);
275
		    interact = 1;
276
		    break;
277
		case 'R':
278
		    sw = 0;
279
		    in = fopen(arg, "r");
280
		    if (in == NULL)
281
			exit(exit_FAILED);
282
		    while (fread(line, 1, 1, in) > 0)
283
			(*eputc) (line[0], out);
284
		    fclose(in);
285
		    break;
286
		case 'u':
287
		    {
288
			char *up;
289
 
290
			for (up = arg; *up; up++)
291
			    (*eputc) (toupper(*up), out);
292
		    }
293
		    sw = 0;
294
		    break;
295
		case 'x':
296
		  xx:{
297
			char *xp;
298
			unsigned int xchr = 1;
299
 
300
			for (xp = arg; *xp; xp++) {
301
			    char ch = *xp;
302
 
303
			    if (!isxdigit(ch))
304
				return 1;
305
			    xchr <<= 4;
306
			    xchr += (isdigit(ch) ? ch - '0' :
307
				     (isupper(ch) ? tolower(ch) : ch)
308
				     - 'a' + 10);
309
			    if (xchr >= 0x100) {
310
				(*eputc) (xchr & 0xff, out);
311
				xchr = 1;
312
			    }
313
			}
314
		    }
315
		    sw = 0;
316
		    break;
317
	    }
318
    }
319
    if (newline)
320
	(*eputc) ('\n', out);
321
    if (out != stdout)
322
	fclose(out);
323
    return exit_OK;
324
}
325
 
326
static int
327
hputc(int ch, FILE * out)
328
{
329
    static const char *hex = "0123456789abcdef";
330
 
331
    /* In environments where char is signed, ch may be negative (!). */
332
    putc(hex[(ch >> 4) & 0xf], out);
333
    putc(hex[ch & 0xf], out);
334
    return 0;
335
}
336
 
337
static int
338
hputs(const char *str, FILE * out)
339
{
340
    while (*str)
341
	hputc(*str++ & 0xff, out);
342
    return 0;
343
}