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