aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-08-05 00:10:46 +0200
committerMattias Andrée <maandree@kth.se>2021-08-05 00:10:50 +0200
commitb91d57b505f560db25b66deff3bae80695c05703 (patch)
tree45ff5b9570d8c3d82ff7c434110e81fdf7219837
parentUpdate config.mk (diff)
downloadgpp-b91d57b505f560db25b66deff3bae80695c05703.tar.gz
gpp-b91d57b505f560db25b66deff3bae80695c05703.tar.bz2
gpp-b91d57b505f560db25b66deff3bae80695c05703.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--README27
-rw-r--r--gpp.123
-rw-r--r--gpp.c197
3 files changed, 132 insertions, 115 deletions
diff --git a/README b/README
index 9d39bdf..8e7137f 100644
--- a/README
+++ b/README
@@ -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
diff --git a/gpp.1 b/gpp.1
index 8841a2e..bf4b982 100644
--- a/gpp.1
+++ b/gpp.1
@@ -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
diff --git a/gpp.c b/gpp.c
index bc466af..c79c822 100644
--- a/gpp.c
+++ b/gpp.c
@@ -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;
}