refactor code
This commit is contained in:
		
							parent
							
								
									a2ae9d1ae8
								
							
						
					
					
						commit
						19f091eead
					
				@ -1,28 +1,22 @@
 | 
			
		||||
all: pscat
 | 
			
		||||
CFLAGS = -g
 | 
			
		||||
RM = rm -f
 | 
			
		||||
TARGETS = pscat
 | 
			
		||||
 | 
			
		||||
all: $(TARGETS)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf ../dist/pscat ../dist/pscat.tar ../dist/pscat.tar.gz pscat
 | 
			
		||||
	$(RM) $(TARGETS)
 | 
			
		||||
 | 
			
		||||
dist: ../dist/pscat.tar.gz
 | 
			
		||||
debug:
 | 
			
		||||
	$(CC) $(DEBUG) -o pscat pscat.c
 | 
			
		||||
 | 
			
		||||
sane: pscat.c ../include/sysexits.h
 | 
			
		||||
	$(CC) -DUSE_ASCII_H -DDONT_USE_SYSTEM_SYSEXITS -o pscat pscat.c
 | 
			
		||||
%.o: %.c %.h
 | 
			
		||||
	$(CC) $(CFLAGS) -c -o %.o %.c
 | 
			
		||||
 | 
			
		||||
pscat: pscat.c
 | 
			
		||||
	$(CC) -o pscat pscat.c
 | 
			
		||||
pscat.o: psargs.h pscat.c
 | 
			
		||||
	$(CC) $(CFLAGS) -DUSE_ASCII_H -DDONT_USE_SYSTEM_SYSEXITS -c -o pscat.o pscat.c
 | 
			
		||||
 | 
			
		||||
../dist/pscat: pscat
 | 
			
		||||
	mkdir -p ../dist/pscat.tmp/bin/ ../dist/pscat.tmp/share/man/man1/
 | 
			
		||||
	cp pscat ../dist/pscat.tmp/bin/pscat
 | 
			
		||||
	cp pscat.1 ../dist/pscat.tmp/share/man/man1/pscat.1
 | 
			
		||||
	mv ../dist/pscat.tmp ../dist/pscat
 | 
			
		||||
pscat: pscat.o psargs.o
 | 
			
		||||
	$(CC) $(CFLAGS) -o pscat psargs.o pscat.o
 | 
			
		||||
 | 
			
		||||
../dist/pscat.tar: ../dist/pscat
 | 
			
		||||
	cd ../dist/pscat && pax -w -x ustar . >../pscat.tar.tmp
 | 
			
		||||
	mv ../dist/pscat.tar.tmp ../dist/pscat.tar
 | 
			
		||||
 | 
			
		||||
../dist/pscat.tar.gz: ../dist/pscat.tar
 | 
			
		||||
	gzip -c <../dist/pscat.tar >../dist/pscat.tar.gz.tmp
 | 
			
		||||
	mv ../dist/pscat.tar.gz.tmp ../dist/pscat.tar.gz
 | 
			
		||||
 | 
			
		||||
.PHONY: all clean sane
 | 
			
		||||
.PHONY: all clean
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								pscat/psargs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								pscat/psargs.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#include "psargs.h"
 | 
			
		||||
 | 
			
		||||
/* Test string containing { c, '\0' } without iteration.
 | 
			
		||||
 * Theoretically saves a little bit of time compared to strcmp(3). */
 | 
			
		||||
#define SCMPFLAT(a, b) (*(a) != '\0' && *((a)+1) == '\0' && *(a) == (b))
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
check_arg(char **args, char l, char r){
 | 
			
		||||
	enum {
 | 
			
		||||
		UNINITIALIZED = 0,
 | 
			
		||||
		NORMAL = 1,
 | 
			
		||||
		INLPAREN = 2
 | 
			
		||||
	} s;
 | 
			
		||||
	int terms;
 | 
			
		||||
 | 
			
		||||
	for(s = UNINITIALIZED, terms = 0; *args != NULL; ++args)
 | 
			
		||||
		switch(s){
 | 
			
		||||
		case UNINITIALIZED: case NORMAL:
 | 
			
		||||
			if(SCMPFLAT(*args, l))
 | 
			
		||||
				s = INLPAREN;
 | 
			
		||||
			else
 | 
			
		||||
				return 0; /* syntax error */
 | 
			
		||||
			break;
 | 
			
		||||
		default: /* >= INLPAREN */
 | 
			
		||||
			/* decrement s if on an rparen, increment if on lparen
 | 
			
		||||
			 * increment terms if on an rparen */
 | 
			
		||||
			if(args[0][1] == '\0'){
 | 
			
		||||
				s += (args[0][0] == l) - (args[0][0] == r);
 | 
			
		||||
				terms += (args[0][0] == r && s == NORMAL);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	/* make sure nothing's open */
 | 
			
		||||
	return terms * (s == NORMAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char **
 | 
			
		||||
corresponding_arg(char **arg, char l, char r){
 | 
			
		||||
	size_t p;
 | 
			
		||||
 | 
			
		||||
	for(p = 1; p > 0;){
 | 
			
		||||
		++arg;
 | 
			
		||||
		/* branching here potentially saves a comparison.
 | 
			
		||||
		 * this seems like the most optimal way to do this,
 | 
			
		||||
		 * maybe it isn't, i don't care too much */
 | 
			
		||||
		if(SCMPFLAT(*arg, l))
 | 
			
		||||
			++p;
 | 
			
		||||
		else if(SCMPFLAT(*arg, r))
 | 
			
		||||
			--p;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return arg;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								pscat/psargs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								pscat/psargs.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
#if !defined _PSARGS_H
 | 
			
		||||
#	define _PSARGS_H
 | 
			
		||||
 | 
			
		||||
/* pscat(1) and pspipe(1) arguments are flanked by { '[', '\0' } and
 | 
			
		||||
 * { ']', '\0' }. Nesting is allowed to facilitate nesting of pscat(1) and
 | 
			
		||||
 * pspipe(1). This checks to make sure grouping symbols in args are balanced.
 | 
			
		||||
 * args is the argv that was passed to main, incremented. l is the left
 | 
			
		||||
 * grouping character (usually '[') and r is the right grouping character
 | 
			
		||||
 * (usually ']').
 | 
			
		||||
 * Returns 0 in the events of a syntax error or there being no arguments.
 | 
			
		||||
 * Otherwise, returns the number of top-level right grouping arguments
 | 
			
		||||
 * (i.e. the number of terms). */
 | 
			
		||||
int check_arg(char **args, char l, char r);
 | 
			
		||||
 | 
			
		||||
/* arg is the location of the argument with the left grouping symbol within
 | 
			
		||||
 * argv, l is the left grouping character itself, r is the right grouping
 | 
			
		||||
 * character itself.
 | 
			
		||||
 * Returns the location of the argument with the corresponding left grouping
 | 
			
		||||
 * symbol within argv. */
 | 
			
		||||
char **corresponding_arg(char **arg, char l, char r);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,12 +1,14 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#ifndef DONT_USE_SYSTEM_SYSEXITS
 | 
			
		||||
#	include <sysexits.h>
 | 
			
		||||
#else
 | 
			
		||||
#	include "../include/sysexits.h"
 | 
			
		||||
#	include "../sysexits/sysexits.h"
 | 
			
		||||
#endif /* ifndef DONT_USE_SYSTEM_SYSEXITS */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "psargs.h"
 | 
			
		||||
 | 
			
		||||
static char *program_name = "pscat";
 | 
			
		||||
 | 
			
		||||
@ -16,56 +18,21 @@ static char *program_name = "pscat";
 | 
			
		||||
#	define L_PAREN '['
 | 
			
		||||
#	define R_PAREN ']'
 | 
			
		||||
#else
 | 
			
		||||
#	include "../include/ascii.h"
 | 
			
		||||
#	include "../ascii/ascii.h"
 | 
			
		||||
#	define L_PAREN ASCII_LEFT_SQUARE_BRACKET
 | 
			
		||||
#	define R_PAREN ASCII_RIGHT_SQUARE_BRACKET
 | 
			
		||||
#endif /* ifndef USE_ASCII_H */
 | 
			
		||||
 | 
			
		||||
/* Test string containing { c, '\0' } without iteration.
 | 
			
		||||
 * Theoretically saves a little bit of time compared to strcmp(3). */
 | 
			
		||||
#define SCMPFLAT(a, b) (*(a) != '\0' && *((a)+1) == '\0' && *(a) == (b))
 | 
			
		||||
 | 
			
		||||
/* Verifies arguments to pscat are sensible. */
 | 
			
		||||
static int
 | 
			
		||||
check_arg(char **argv){
 | 
			
		||||
	enum {
 | 
			
		||||
		UNINITIALIZED = 0,
 | 
			
		||||
		NORMAL = 1,
 | 
			
		||||
		INLPAREN = 2
 | 
			
		||||
	} s;
 | 
			
		||||
	int terms;
 | 
			
		||||
 | 
			
		||||
	for(s = UNINITIALIZED, terms = 0; *argv != NULL; ++argv)
 | 
			
		||||
		switch(s){
 | 
			
		||||
		case UNINITIALIZED: case NORMAL:
 | 
			
		||||
			if(SCMPFLAT(*argv, L_PAREN))
 | 
			
		||||
				s = INLPAREN;
 | 
			
		||||
			else
 | 
			
		||||
				return 0; /* syntax error */
 | 
			
		||||
			break;
 | 
			
		||||
		default: /* >= INLPAREN */
 | 
			
		||||
			if(argv[0][1] == '\0'){
 | 
			
		||||
				s -= (argv[0][0] == R_PAREN);
 | 
			
		||||
				terms += (argv[0][0] == R_PAREN && s == NORMAL);
 | 
			
		||||
				s += (argv[0][0] == L_PAREN);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	return terms;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]){
 | 
			
		||||
	char **psstart;
 | 
			
		||||
	int child;
 | 
			
		||||
	int i;
 | 
			
		||||
	int p;
 | 
			
		||||
	int retval;
 | 
			
		||||
	int terms;
 | 
			
		||||
 | 
			
		||||
	retval = 0;
 | 
			
		||||
 | 
			
		||||
	if((terms = check_arg(++argv)) == 0){
 | 
			
		||||
	if((terms = check_arg(++argv, L_PAREN, R_PAREN)) == 0){
 | 
			
		||||
		fprintf(stderr,
 | 
			
		||||
			"Usage: %s \"[\" [utility [argument...]] \"]\" ...\n",
 | 
			
		||||
			argv[0] == NULL ? program_name : argv[0]
 | 
			
		||||
@ -75,18 +42,8 @@ int main(int argc, char *argv[]){
 | 
			
		||||
 | 
			
		||||
	/* loop starts with *argv -> the next L_PAREN */
 | 
			
		||||
	for(i = 0; i < terms; ++i){
 | 
			
		||||
		psstart = ++argv;
 | 
			
		||||
		p = 1;
 | 
			
		||||
		while(p > 0){
 | 
			
		||||
			++argv;
 | 
			
		||||
			/* branching here potentially saves a comparison.
 | 
			
		||||
			 * this seems like the most optimal way to do this,
 | 
			
		||||
			 * maybe it isn't, i don't care too much */
 | 
			
		||||
			if(SCMPFLAT(*argv, L_PAREN))
 | 
			
		||||
				++p;
 | 
			
		||||
			else if(SCMPFLAT(*argv, R_PAREN))
 | 
			
		||||
				--p;
 | 
			
		||||
		}
 | 
			
		||||
		psstart = argv + 1;
 | 
			
		||||
		argv = corresponding_arg(argv, L_PAREN, R_PAREN);
 | 
			
		||||
		/* *argv -> the corresponding R_PAREN. turn it into NULL to
 | 
			
		||||
		 * terminate the argument list to send to execvp(3) */
 | 
			
		||||
		*argv = NULL;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user