diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2019-10-15 12:24:12 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2020-08-13 11:26:55 +0200 |
commit | e088156d5b620e5e639580dacf85c6dc13823c74 (patch) | |
tree | 57f5c025e203279944da512166c20bc0521d8ccd /base/echogs.c | |
download | ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.gz ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.bz2 ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.zip |
Import Ghostscript 9.50ghostscript-9.50
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'base/echogs.c')
-rw-r--r-- | base/echogs.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/base/echogs.c b/base/echogs.c new file mode 100644 index 00000000..ae68402c --- /dev/null +++ b/base/echogs.c @@ -0,0 +1,355 @@ +/* Copyright (C) 2001-2019 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* 'echo'-like utility */ + +#include "stdpre.h" +#include <stdio.h> +#include <stdlib.h> + +#if defined(__sun__) && !defined(const) +/* Apparently, there are archaic Sun platforms which don't include + * prototypes for fputc/fputs in stdio.h. The following prototype can + * cause type mismatches if const has been defined (usually with + * -Dconst=), so it's only included if const is undefined. + */ +extern int fputc(int, FILE *), fputs(const char *, FILE *); +#endif + +/* Some systems have time_t in sys/types.h rather than time.h. */ +#include <sys/types.h> +#include <ctype.h> +#include <string.h> +#include <time.h> /* for ctime */ + +/* + * This program exists solely to get around omissions, problems, and + * incompatibilities in various shells and utility environments. + * Don't count on it staying the same from one release to another! + */ + +/* + * Usage: + echogs [-e .extn] [-(w|a)[b][-] file] [-h] [-n] + (-b|-B | -d|-D | -f|-F | -x hexstring | -(l|q|Q) string | -(l|q|Q)string | + -s | -u string | -i | -r file | -R file | -X)* + [-] string* + * Echoes string(s), or the binary equivalent of hexstring(s). + * If -w, writes to file; if -a, appends to file; if neither, + * writes to stdout. -wb and -ab open the file in binary mode. + * -w and -a search forward for the next argument that is not a switch. + * An appended - means the same as - alone, taking effect after the file + * argument. + * -e specifies an extension to be added to the file name. + * If -h, write the output in hex instead of literally. + * If -n, does not append a newline to the output. + * -b or -B means insert the base part (minus directories) of the file name + * passed as the argument of -w or -a. + * -d or -D means insert the date and time. + * -f or -F means insert the file name passed as the argument of -w or -a. + * -q means write the next string literally. + * -l or -Q means the same as -q followed by -s. + * -s means write a space. + * -u means convert the next string to upper case. + * -i means read from stdin, treating each line as an argument. + * -r means read from a named file in the same way. + * -R means copy a named file with no interpretation + * (but convert to hex if -h is in effect). + * -X means treat any following literals as hex rather than string data. + * - or -+ alone means treat the rest of the line as literal data, + * even if the first string begins with a -. + * -+<letter> is equivalent to -<Letter>, i.e., it upper-cases the letter. + * Inserts spaces automatically between the trailing strings, + * but nowhere else; in particular, + echogs -q a b + * writes 'ab', in contrast to + echogs -q a -s b + * which writes 'a b'. + */ + +static int hputc(int, FILE *), hputs(const char *, FILE *); + +int +main(int argc, char *argv[]) +{ + FILE *out = stdout; + /* + * The initialization in = 0 is unnecessary: in is only referenced if + * interact = 1, in which case in has always been initialized. + * We initialize in = 0 solely to pacify stupid compilers. + */ + FILE *in = 0; + const char *extn = ""; + char fmode[5] = {0}; +#define FNSIZE 4096 + char *fnparam = NULL; /* Initialisation to shut up compilers */ + char fname[FNSIZE]; + int newline = 1; + int interact = 0; + int (*eputc)(int, FILE *) = fputc; + int (*eputs)(const char *, FILE *) = fputs; +#define LINESIZE 1000+FNSIZE +#define LINESIZESLOP LINESIZE + 10 + char line[LINESIZESLOP]; + char sw = 0, sp = 0, hexx = 0; + char **argp = argv + 1; + int nargs = argc - 1; + + if (nargs > 0 && !strcmp(*argp, "-e")) { + if (nargs < 2) + return 1; + extn = argp[1]; + argp += 2, nargs -= 2; + } + if (nargs > 0 && (*argp)[0] == '-' && + ((*argp)[1] == 'w' || (*argp)[1] == 'a') + ) { + size_t len = strlen(*argp); + int i; + + if (len > 4) + return 1; + for (i = 1; i < nargs; i++) + if (argp[i][0] != '-') + break; + if (i == nargs) + return 1; + fnparam = argp[i]; + strncpy(fmode, *argp + 1, 4); + if (strlen(fnparam) + strlen(extn) >= FNSIZE) { + fputs("File param size exceeded\n", stderr); + return 1; + } + strcpy(fname, fnparam); + strcat(fname, extn); + if (fmode[len - 2] == '-') { + /* + * The referents of argp are actually const, but they can't be + * declared that way, so we have to make a writable constant. + */ + static char dash[2] = { '-', 0 }; + + fmode[len - 2] = 0; + argp[i] = dash; + argp++, nargs--; + } else { + for (; i > 1; i--) + argp[i] = argp[i - 1]; + argp += 2, nargs -= 2; + } + } else { + strcpy(fname, ""); + fnparam = fname; /* quieten static analysis */ + } + if (nargs > 0 && !strcmp(*argp, "-h")) { + eputc = hputc, eputs = hputs; + argp++, nargs--; + } + if (nargs > 0 && !strcmp(*argp, "-n")) { + newline = 0; + argp++, nargs--; + } + if (strlen(fname) != 0) { + out = fopen(fname, fmode); + if (out == 0) + return 1; + } + while (1) { + char *arg; + int i; + + if (interact) { + if (fgets(line, LINESIZESLOP, in) == NULL) { + interact = 0; + if (in != stdin) + fclose(in); + continue; + } + /* Remove the terminating \n. */ + if (strlen(line) > LINESIZE) { + fputs("Line limit exceeded\n", stderr); + return 1; + } + for (i = strlen(line) - 1; i < LINESIZESLOP; i++) { + line[i] = 0; + } + arg = line; + } else { + if (nargs == 0) + break; + arg = *argp; + argp++, nargs--; + } + if (sw == 0 && arg[0] == '-') { + char chr = arg[1]; + + sp = 0; + swc:switch (chr) { + case 'l': /* literal string, then -s */ + chr = 'Q'; + /* falls through */ + case 'q': /* literal string */ + case 'Q': /* literal string, then -s */ + if (arg[2] != 0) { + (*eputs) (arg + 2, out); + if (chr == 'Q') + (*eputc) (' ', out); + break; + } + /* falls through */ + case 'r': /* read from a file */ + case 'R': + case 'u': /* upper-case string */ + case 'x': /* hex string */ + sw = chr; + break; + case 's': /* write a space */ + (*eputc) (' ', out); + break; + case 'i': /* read interactively */ + interact = 1; + in = stdin; + break; + case 'b': /* insert base file name */ + case 'B': + arg = fnparam + strlen(fnparam); + while (arg > fnparam && + (isalnum(arg[-1]) || arg[-1] == '_')) + --arg; + (*eputs) (arg, out); + break; + case 'd': /* insert date/time */ + case 'D': + { + time_t t; + char str[26]; + + time(&t); + strncpy(str, ctime(&t), 25); + str[24] = 0; /* remove \n */ + (*eputs) (str, out); + } break; + case 'f': /* insert file name */ + case 'F': + (*eputs) (fnparam, out); + break; + case 'X': /* treat literals as hex */ + hexx = 1; + break; + case '+': /* upper-case command */ + if (arg[1]) { + ++arg; + chr = toupper(arg[1]); + goto swc; + } + /* falls through */ + case 0: /* just '-' */ + sw = '-'; + break; + } + } else + switch (sw) { + case 0: + case '-': + if (hexx) + goto xx; + if (sp) + (*eputc) (' ', out); + (*eputs) (arg, out); + sp = 1; + break; + case 'q': + sw = 0; + (*eputs) (arg, out); + break; + case 'Q': + sw = 0; + (*eputs) (arg, out); + (*eputc) (' ', out); + break; + case 'r': + sw = 0; + in = fopen(arg, "r"); + if (in == NULL) + exit(exit_FAILED); + interact = 1; + break; + case 'R': + sw = 0; + in = fopen(arg, "r"); + if (in == NULL) + exit(exit_FAILED); + while (fread(line, 1, 1, in) > 0) + (*eputc) (line[0], out); + fclose(in); + break; + case 'u': + { + char *up; + + for (up = arg; *up; up++) + (*eputc) (toupper(*up), out); + } + sw = 0; + break; + case 'x': + xx:{ + char *xp; + unsigned int xchr = 1; + + for (xp = arg; *xp; xp++) { + char ch = *xp; + + if (!isxdigit(ch)) + return 1; + xchr <<= 4; + xchr += (isdigit(ch) ? ch - '0' : + (isupper(ch) ? tolower(ch) : ch) + - 'a' + 10); + if (xchr >= 0x100) { + (*eputc) (xchr & 0xff, out); + xchr = 1; + } + } + } + sw = 0; + break; + } + } + if (newline) + (*eputc) ('\n', out); + if (out != stdout) + fclose(out); + return exit_OK; +} + +static int +hputc(int ch, FILE * out) +{ + static const char *hex = "0123456789abcdef"; + + /* In environments where char is signed, ch may be negative (!). */ + putc(hex[(ch >> 4) & 0xf], out); + putc(hex[ch & 0xf], out); + return 0; +} + +static int +hputs(const char *str, FILE * out) +{ + while (*str) + hputc(*str++ & 0xff, out); + return 0; +} |