diff options
-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; } |