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-807a63c89da8b09e815ca6e2fbdc297b60d8fba1.tar.gz gpp-807a63c89da8b09e815ca6e2fbdc297b60d8fba1.tar.bz2 gpp-807a63c89da8b09e815ca6e2fbdc297b60d8fba1.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;  } | 
