aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-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;
}