diff options
author | Mattias Andrée <maandree@kth.se> | 2021-08-05 00:10:46 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2021-08-05 00:10:50 +0200 |
commit | b91d57b505f560db25b66deff3bae80695c05703 (patch) | |
tree | 45ff5b9570d8c3d82ff7c434110e81fdf7219837 | |
parent | Update config.mk (diff) | |
download | gpp-2.1.tar.gz gpp-2.1.tar.bz2 gpp-2.1.tar.xz |
Standardise @(( )), add -R option, and fix critical bug2.1
The bug was that if the code buffered was increased,
the new character that should have been pushed to it
was not pushed into the code buffer, leaving out some
characters before preprocessing takes place.
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | README | 27 | ||||
-rw-r--r-- | gpp.1 | 23 | ||||
-rw-r--r-- | gpp.c | 197 |
3 files changed, 132 insertions, 115 deletions
@@ -3,7 +3,8 @@ NAME SYNOPSIS gpp [-D name[=value]] [-f file | [-i input-file] - [-o output-file]] [-n count] [-s symbol] [-u [-u]] + [-o output-file]] [-n count] [-s symbol] + [-R macroline-replacement-text] [-u [-u]] [shell [argument] ...] ETYMOLOGY @@ -35,10 +36,13 @@ DESCRIPTION Additionally, gpp supports variable substitution. @{VARIABLE} will be replaces by the value if the variable (possibility environment variable) VARIABLE. - gpp supports all modifiers thats Bash supports. For - example, if you want the value to be included but - uppercase you can write @{VARIABLE^^}, or @{VARIABLE,,} - for lowercase. + gpp supports all modifiers thats Bash (or which ever + shell is selected) supports. For example, if you want + the value to be included but uppercase you can write + @{VARIABLE^^}, or @{VARIABLE,,} for lowercase. gpp + also supports mathematical expressions that the via + the shells $((EXPRESSION)) syntax, by using + @((EXPRESSION)). Everything that is not a preprocessing directive is echo verbatim, except all @@ are replaced by @. @@ -56,18 +60,23 @@ OPTIONS Equivalent to -i FILE -o FILE. -i input-file - Select file to process. Defaults to /dev/stdin. + Select file to process. Default value is /dev/stdin. -n count Process the file recursively count times. - Defaults to 1 time. + Default value is 1. -o output-file - Select output file. Defaults to /dev/stdout. + Select output file. Defaults value is /dev/stdout. + + -R macroline-replacement-text + Text to replace macrolines with in the output. + You may for example want to use % for TeX files. + Default value is the empty string. -s symbol Set the prefix symbol for preprocessor directives. - Defaults to @. + Default value is @. -u Clear the shebang line, remove it if this flag @@ -14,6 +14,8 @@ gpp - Bash-based preprocessor for anything .IR output-file ]] [-n .IR count ] +[-R +.IR macroline-replacement-text ] [-s .IR symbol ] [-u [-u]] @@ -77,12 +79,20 @@ will be replaces by the value if the variable .B gpp supports all modifiers that .BR bash (1) -supports. For example, if you want the value to be -included but uppercase you can write +(or which ever +.I shell +is selected) supports. For example, if you want the +value to be included but uppercase you can write .BR @{ \fIVARIABLE\fP ^^} , or .BI @{ VARIABLE ,,} for lowercase. +.B gpp +also supports mathematical expressions that the via +the shells +.BI $(( EXPRESSION )) +syntax, by using +.BR @(( \fIEXPRESSION\fP )) . .PP Everything that is not a preprocessing directive is echo verbatim, except all @@ -130,6 +140,13 @@ Select output file. If is specified, /dev/stdout will be used. Default value is /dev/stdout. .TP +.BI \-R\ macroline-replacement-text +Text to replace macrolines with in the output. +You may for example want to use +.B % +for TeX files. +Default value is the empty string. +.TP .BI \-s\ symbol Set the prefix symbol for preprocessor directives. Default value is @@ -336,7 +353,7 @@ preprocessors. .SH NOTES None. -.SH BUS +.SH BUGS None. .SH FUTURE DIRECTIONS @@ -22,7 +22,37 @@ static void usage(void) { fprintf(stderr, "usage: %s [-D name[=value]] [-f file | [-i input-file] [-o output-file]] " - "[-n count] [-s symbol] [-u [-u]] [shell [argument] ...]\n", argv0); + "[-n count] [-R macroline-replacement-text] [-s symbol] [-u [-u]] " + "[shell [argument] ...]\n", argv0); + exit(1); +} + + +static void +vweprintf(const char *fmt, va_list ap) +{ + int errnum = errno; + fprintf(stderr, "%s: ", argv0); + vfprintf(stderr, fmt, ap); + fprintf(stderr, " %s\n", strerror(errnum)); +} + +static void +weprintf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vweprintf(fmt, ap); + va_end(ap); +} + +static void +eprintf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vweprintf(fmt, ap); + va_end(ap); exit(1); } @@ -67,10 +97,8 @@ xopen(const char *path, int *do_close) return fd; } fd = open(path, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: open %s O_RDONLY: %s\n", argv0, path, strerror(errno)); - exit(1); - } + if (fd < 0) + eprintf("open %s O_RDONLY:", path); *do_close = 1; return fd; } @@ -83,10 +111,8 @@ xcreate(const char *path) if (fd >= 0) return fd; fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (fd < 0) { - fprintf(stderr, "%s: open %s O_WRONLY|O_CREAT|O_TRUNC 0666: %s\n", argv0, path, strerror(errno)); - exit(1); - } + if (fd < 0) + eprintf("open %s O_WRONLY|O_CREAT|O_TRUNC 0666:", path); return fd; } @@ -103,10 +129,8 @@ append(char **restrict out_datap, size_t *restrict out_lenp, size_t *restrict ou if (*out_lenp + len + 1 > *out_sizep) { *out_sizep = *out_lenp + len + 1; *out_datap = realloc(*out_datap, *out_sizep); - if (!*out_datap) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - exit(1); - } + if (!*out_datap) + eprintf("realloc:"); } vsprintf(&(*out_datap)[*out_lenp], fmt, ap); *out_lenp += len; @@ -121,6 +145,7 @@ main(int argc, char *argv[]) const char *input_file = NULL; const char *output_file = NULL; const char *symbol = NULL; + const char *replacement = NULL; size_t symlen = 1; int iterations = -1; int unshebang = 0; @@ -135,7 +160,7 @@ main(int argc, char *argv[]) char buffer[4096], c, *quotes = NULL, quote; size_t brackets, nquotes, quotes_size = 0; int symb, esc, dollar; - size_t len, j, lineno, no = 0, cnt; + size_t len, j, lineno, no = 0; int i, n, status, state, entered; ssize_t r; pid_t pid; @@ -148,10 +173,8 @@ main(int argc, char *argv[]) p = strchr(arg, '='); if (p) *p++ = '\0'; - if (setenv(arg, p ? p : "1", 1)) { - fprintf(stderr, "%s: setenv %s %s 1: %s\n", argv0, arg, p ? p : "1", strerror(errno)); - return 1; - } + if (setenv(arg, p ? p : "1", 1)) + eprintf("setenv %s %s 1:", arg, p ? p : "1"); break; case 'f': if (input_file || output_file) @@ -186,6 +209,11 @@ main(int argc, char *argv[]) if (!*output_file) usage(); break; + case 'R': + if (replacement) + usage(); + replacement = EARGF(usage()); + break; case 's': if (symbol) usage(); @@ -210,10 +238,12 @@ main(int argc, char *argv[]) } if (setenv("_GPP", argv0, 1)) - fprintf(stderr, "%s: setenv _GPP %s 1: %s\n", argv0, argv0, strerror(errno)); + weprintf("setenv _GPP %s 1:", argv0); if (iterations < 0) iterations = 1; + if (!replacement) + replacement = ""; if (!symbol) symbol = "@"; if (!input_file || (input_file[0] == '-' && !input_file[1])) @@ -225,16 +255,14 @@ main(int argc, char *argv[]) for (;;) { if (in_len == in_size) { in_data = realloc(in_data, in_size += 8096); - if (!in_data) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - return 1; - } + if (!in_data) + eprintf("realloc:"); } r = read(in_fd, &in_data[in_len], in_size - in_len); if (r <= 0) { if (!r) break; - fprintf(stderr, "%s: read %s: %s\n", argv0, input_file, strerror(errno)); + eprintf("read %s:", input_file); } in_len += (size_t)r; } @@ -261,7 +289,7 @@ after_unshebang: while (iterations--) { entered = 0; state = 0; - lineno = 0; + lineno = 1; brackets = nquotes = 0; symb = esc = dollar = 0; while (in_off < in_len) { @@ -269,6 +297,7 @@ after_unshebang: preprocess: c = in_data[in_off++]; if (c == '\n') { + lineno += 1; state = 0; brackets = nquotes = 0; symb = esc = dollar = 0; @@ -302,10 +331,8 @@ after_unshebang: add_to_quotes: if (nquotes == quotes_size) { quotes = realloc(quotes, quotes_size += 1); - if (!quotes) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - return 1; - } + if (!quotes) + eprintf("realloc:"); } quotes[nquotes++] = quote; } else if (c == ')' || c == '}') { @@ -340,29 +367,26 @@ after_unshebang: } else { if (out_len == out_size) { out_data = realloc(out_data, out_size += 4096); - if (!out_data) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - return 1; - } - } else { - if ((out_data[out_len++] = c) == '\n') - state = 0; + if (!out_data) + eprintf("realloc:"); + } + if ((out_data[out_len++] = c) == '\n') { + lineno += 1; + state = 0; } } } else if (state == 1) { append_char: if (out_len == out_size) { out_data = realloc(out_data, out_size += 4096); - if (!out_data) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - return 1; - } - } else { - if ((out_data[out_len++] = in_data[in_off++]) == '\n') - state = 0; + if (!out_data) + eprintf("realloc:"); + } + if ((out_data[out_len++] = in_data[in_off++]) == '\n') { + lineno += 1; + state = 0; } } else { - lineno += 1; if (in_len - in_off > symlen && !memcmp(&in_data[in_off], symbol, symlen) && (in_data[in_off + symlen] == '<' || in_data[in_off + symlen] == '>')) { state = 1; @@ -383,31 +407,23 @@ after_unshebang: in_len = 0; in_off = 0; - if (pipe(fds_in) || pipe(fds_out)) { - fprintf(stderr, "%s: pipe: %s\n", argv0, strerror(errno)); - return 1; - } + if (pipe(fds_in) || pipe(fds_out)) + eprintf("pipe:"); pid = fork(); switch (pid) { case -1: - fprintf(stderr, "%s: fork: %s\n", argv0, strerror(errno)); - return 1; + eprintf("fork:"); case 0: close(fds_in[1]); close(fds_out[0]); - if (dup2(fds_in[0], STDIN_FILENO) != STDIN_FILENO) { - fprintf(stderr, "%s: dup2 <pipe> STDIN_FILENO: %s\n", argv0, strerror(errno)); - return 1; - } - if (dup2(fds_out[1], STDOUT_FILENO) != STDOUT_FILENO) { - fprintf(stderr, "%s: dup2 <pipe> STDOUT_FILENO: %s\n", argv0, strerror(errno)); - return 1; - } + if (dup2(fds_in[0], STDIN_FILENO) != STDIN_FILENO) + eprintf("dup2 <pipe> STDIN_FILENO:"); + if (dup2(fds_out[1], STDOUT_FILENO) != STDOUT_FILENO) + eprintf("dup2 <pipe> STDOUT_FILENO:"); close(fds_in[0]); close(fds_out[1]); execvp(*shell, (void *)shell); - fprintf(stderr, "%s: execvp %s: %s\n", argv0, *shell, strerror(errno)); - return 1; + eprintf("execvp %s:", *shell); default: close(fds_in[0]); close(fds_out[1]); @@ -422,35 +438,27 @@ after_unshebang: state = 0; while (npfds) { n = poll(pfds, npfds, -1); - if (n < 0) { - fprintf(stderr, "%s: poll: %s\n", argv0, strerror(errno)); - return 1; - } + if (n < 0) + eprintf("poll:"); for (i = 0; i < n; i++) { if (!pfds[i].revents) continue; if (pfds[i].fd == fds_in[1]) { if (out_off == out_len) { - if (close(fds_in[1])) { - fprintf(stderr, "%s: write <pipe>: %s\n", argv0, strerror(errno)); - return 1; - } + if (close(fds_in[1])) + eprintf("write <pipe>:"); pfds[i] = pfds[--npfds]; continue; } r = write(fds_in[1], &out_data[out_off], out_len - out_off); - if (r <= 0) { - fprintf(stderr, "%s: write <pipe>: %s\n", argv0, strerror(errno)); - return 1; - } + if (r <= 0) + eprintf("write <pipe>:"); out_off += (size_t)r; } else { r = read(fds_out[0], buffer, sizeof(buffer)); if (r <= 0) { - if (r < 0 || close(fds_out[0])) { - fprintf(stderr, "%s: read <pipe>: %s\n", argv0, strerror(errno)); - return 1; - } + if (r < 0 || close(fds_out[0])) + eprintf("read <pipe>:"); pfds[i] = pfds[--npfds]; continue; } @@ -485,20 +493,9 @@ after_unshebang: } no = no * 10 + (buffer[j] & 15); } else if (!buffer[j]) { - if (no > lineno) { - cnt = no - lineno; - lineno = no; - if (in_len + cnt > in_size) { - in_size = in_len + cnt; - in_data = realloc(in_data, in_size); - if (!in_data) { - fprintf(stderr, "%s: realloc: %s\n", - argv0, strerror(errno)); - return 1; - } - } - while (cnt--) - in_data[in_len++] = '\n'; + while (lineno < no) { + append(&in_data, &in_len, &in_size, "%s\n", replacement); + lineno += 1; } state = 3; } else { @@ -512,10 +509,8 @@ after_unshebang: if (in_len == in_size) { in_size += 4096; in_data = realloc(in_data, in_size); - if (!in_data) { - fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); - return 1; - } + if (!in_data) + eprintf("realloc:"); } in_data[in_len++] = buffer[j]; if (buffer[j] == '\n') { @@ -528,10 +523,8 @@ after_unshebang: } } } - if (waitpid(pid, &status, 0) != pid) { - fprintf(stderr, "%s: waitpid %s <&status> 0: %s\n", argv0, *shell, strerror(errno)); - return 1; - } + if (waitpid(pid, &status, 0) != pid) + eprintf("waitpid %s <&status> 0:", *shell); if (status) return WIFEXITED(status) ? WEXITSTATUS(status) : 1; @@ -546,14 +539,12 @@ after_unshebang: out_fd = xcreate(output_file); while (in_off < in_len) { r = write(out_fd, &in_data[in_off], in_len - in_off); - if (r <= 0) { - fprintf(stderr, "%s: write %s: %s\n", argv0, output_file, strerror(errno)); - return 1; - } + if (r <= 0) + eprintf("write %s:", output_file); in_off += (size_t)r; } if (close(out_fd)) - fprintf(stderr, "%s: write %s: %s\n", argv0, output_file, strerror(errno)); + eprintf("write %s:", output_file); free(in_data); return 0; } |