diff options
| -rw-r--r-- | src/bin/main.c | 75 | ||||
| -rw-r--r-- | src/include/aplwc.h | 15 | ||||
| -rw-r--r-- | src/include/aplwc_macros.h | 1 | ||||
| -rw-r--r-- | src/lib/main.c | 46 | ||||
| -rw-r--r-- | tests/Makefile.am | 1 | ||||
| -rwxr-xr-x | tests/run_script_test.sh | 10 | ||||
| -rwxr-xr-x | tests/run_simple_test.sh | 10 | ||||
| -rwxr-xr-x | tests/scripts/bad/6.sh | 4 | ||||
| -rwxr-xr-x | tests/scripts/simfail.sh | 40 |
9 files changed, 139 insertions, 63 deletions
diff --git a/src/bin/main.c b/src/bin/main.c index d0328f0..a969956 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -23,12 +23,14 @@ #include <errno.h> #include "aplwc_repl.h" +static unsigned long failsim_start; +static unsigned long failsim_count; + static void * my_alloc(size_t size, size_t *actual) { size_t target = size; void *p; - int fail2; if(actual){ if(NEVER(target == 0)) @@ -45,12 +47,11 @@ my_alloc(size_t size, size_t *actual) } } - fail2 = aplwc_simulate_failure(); p = FAILCASE(malloc(target), NULL); if((p == NULL) && (size < target)){ target = size; - p = FAILCASE_X(malloc(target), NULL, fail2); + p = FAILCASE(malloc(target), NULL); } if(actual) @@ -64,6 +65,19 @@ my_dealloc(void *p) free(p); } +static unsigned long +my_setup_failsim(enum aplwc_failsim_parameter p, unsigned long def) +{ + switch(p){ + case APLWC_FAILSIM_START: + return failsim_start = getenv_ulong("APLWC_SIMULATE_FAILURE_START", def); + case APLWC_FAILSIM_COUNT: + return failsim_count = getenv_ulong("APLWC_SIMULATE_FAILURE_COUNT", def); + default: + return def; + } +} + int main(int argc, char *argv[]) { @@ -73,28 +87,25 @@ main(int argc, char *argv[]) AplwcLine line; AplwcValue value; char *input, *src; - int exit_code, line_number; + int line_number; size_t input_size, src_size, i; int opt, xflag, input_file; long tmp; - unsigned long print_failsims; FILE *f; + unsigned long failsim_count, failsim_fails; aplwc_clear_line(&line); aplwc_clear_value(&value); input = NULL; xflag = 0; input_file = 0; - exit_code = 0; line_number = 0; aplwc = NULL; - aplwc_simulate_failure_at = getenv_ulong("APLWC_SIMULATE_FAILURE_AT", 0); - print_failsims = getenv_ulong("APLWC_SIMULATE_FAILURE_PRINT_COUNT", 0); - memset(&fns, 0, sizeof(fns)); fns.alloc = my_alloc; fns.dealloc = my_dealloc; + fns.setup_failsim = my_setup_failsim; while((opt = getopt(argc, argv, "x")) != -1){ switch(opt){ @@ -104,7 +115,7 @@ main(int argc, char *argv[]) default: usage: fprintf(stderr, "Usage: %s [-x] [file]\n", argv[0]); - exit_code = 1; + ret = APLWC_OTHER_FAILURE; goto end; } } @@ -114,7 +125,7 @@ usage: f = fopen(argv[optind], "r"); if(f == NULL){ fprintf(stderr, "Could not open file: %s: %s\n", argv[optind], strerror(errno)); - exit_code = 1; + ret = APLWC_OTHER_FAILURE; goto end; } }else if(optind == argc) @@ -125,7 +136,6 @@ usage: aplwc = aplwc_new(fns, &ret); if(ret){ fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); - exit_code = 1; goto end; } @@ -133,7 +143,7 @@ usage: if(FAILCASE(fseek(f, 0, SEEK_END), -1)){ file_size: fprintf(stderr, "Failed to determine file size\n"); - exit_code = 1; + ret = APLWC_OTHER_FAILURE; goto end; } tmp = FAILCASE(ftell(f), -1); @@ -144,12 +154,12 @@ file_size: input = FAILCASE(malloc(input_size), NULL); if(input == NULL){ fprintf(stderr, "Failed to allocate space for file contents\n"); - exit_code = 1; + ret = APLWC_OTHER_FAILURE; goto end; } if(FAILCASE(fread(input, 1, input_size, f), 0) < input_size){ fprintf(stderr, "Failed to read file contents\n"); - exit_code = 1; + ret = APLWC_OTHER_FAILURE; goto end; } fclose(f); @@ -170,7 +180,6 @@ file_size: ret = aplwc_load_module(aplwc, "Main", src, src_size); if(ret){ fprintf(stderr, "Couldn't load Main module from file %s: %s\n", argv[optind], aplwc_errstr_rc(ret)); - exit_code = 1; goto end; } free(input); @@ -199,7 +208,11 @@ file_size: if(!aplwc_valid_line(&line)){ line_error: fprintf(stderr, "error on line %d: %s: %s\n", line_number, aplwc_errstr(aplwc), input); - continue; + if(aplwc_failsim_query(APLWC_FAILSIM_COUNT) > 0){ + ret = aplwc_last_error(aplwc); + goto end; + }else + continue; } aplwc_eval(&line, &value); if(!aplwc_valid_value(&value)) @@ -218,19 +231,23 @@ end: if(aplwc) aplwc_destroy(aplwc); - if(print_failsims){ - f = fdopen(3, "w"); - if(f == NULL){ - fprintf(stderr, "Failed to open fd 3\n"); - exit_code = 1; - }else{ - fprintf(f, "%ld\n", aplwc_simulate_failure_count); - fclose(f); + failsim_count = aplwc_failsim_query(APLWC_FAILSIM_COUNT); + failsim_fails = aplwc_failsim_query(APLWC_FAILSIM_FAILS); + if(failsim_count > 0){ + switch(ret){ + case APLWC_OK: + case APLWC_OTHER_FAILURE: + case APLWC_OUT_OF_MEMORY: + break; + default: + return 97; } - } - if((exit_code != 0) && aplwc_simulate_failure_at && (aplwc_simulate_failure_count >= aplwc_simulate_failure_at)) - exit_code = 0; + if(failsim_count > failsim_fails) + return 98; + else + return 99; + } - return exit_code; + return (ret != APLWC_OK); } diff --git a/src/include/aplwc.h b/src/include/aplwc.h index 5a6cb79..09507a1 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -29,6 +29,7 @@ enum aplwc_rc { APLWC_NOT_YET_IMPLEMENTED, APLWC_INVALID_UTF8, APLWC_INVALID_SYNTAX, + APLWC_OTHER_FAILURE, APLWC_RC_LAST = APLWC_INVALID_SYNTAX }; @@ -44,14 +45,21 @@ struct aplwc_ref { typedef struct { struct aplwc_ref ref; } AplwcLine; typedef struct { struct aplwc_ref ref; } AplwcValue; +enum aplwc_failsim_parameter { + APLWC_FAILSIM_START, + APLWC_FAILSIM_COUNT, + APLWC_FAILSIM_HITS, + APLWC_FAILSIM_FAILS, + + APLWC_FAILSIM_PARAMETER_COUNT /* Not a real parameter, just the count */ +}; + struct aplwc_fns { void *(*alloc)(size_t, size_t *); void (*dealloc)(void *); + unsigned long (*setup_failsim)(enum aplwc_failsim_parameter, unsigned long); }; -extern uint64_t aplwc_simulate_failure_at; -extern uint64_t aplwc_simulate_failure_count; - struct aplwc *aplwc_new(struct aplwc_fns, enum aplwc_rc *); void aplwc_destroy(struct aplwc *); void aplwc_clear_line(AplwcLine *); @@ -67,6 +75,7 @@ void aplwc_eval(AplwcLine *, AplwcValue *); void aplwc_free_value(AplwcValue *); const char *aplwc_value_string(AplwcValue *); enum aplwc_rc aplwc_load_module(struct aplwc *, const char *, const char *, int n); +unsigned long aplwc_failsim_query(enum aplwc_failsim_parameter); int aplwc_simulate_failure(void); #endif /* APLWC_H */ diff --git a/src/include/aplwc_macros.h b/src/include/aplwc_macros.h index 3c8aa6b..d1e50e4 100644 --- a/src/include/aplwc_macros.h +++ b/src/include/aplwc_macros.h @@ -41,6 +41,5 @@ #endif #define FAILCASE(x, fail) (aplwc_simulate_failure() ? (fail) : (x)) -#define FAILCASE_X(x, fail, test) ((test) ? (fail) : (x)) #endif /* APLWC_MACROS_H */ diff --git a/src/lib/main.c b/src/lib/main.c index d25ad99..6cfff40 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -20,12 +20,17 @@ #include "aplwc_internal.h" #include "boot.h" +static void aplwc_failsim_init(unsigned long (*)(enum aplwc_failsim_parameter, unsigned long)); + struct aplwc * aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp) { enum aplwc_rc rc; struct aplwc *aplwc; + if(fns.setup_failsim) + aplwc_failsim_init(fns.setup_failsim); + aplwc = NULL; if(fns.alloc == NULL){ rc = APLWC_OUT_OF_MEMORY; @@ -41,7 +46,8 @@ aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp) aplwc->fns = fns; aplwc->symtab = NULL; memory_init(aplwc); - keyword_init(aplwc); + if((rc = keyword_init(aplwc)) != APLWC_OK) + goto end; rc = aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); end: @@ -231,15 +237,39 @@ aplwc_valid_line(AplwcLine *l) return valid_ref(&l->ref); } -uint64_t aplwc_simulate_failure_at; -uint64_t aplwc_simulate_failure_count; +static unsigned long aplwc_failsim_properties[APLWC_FAILSIM_PARAMETER_COUNT]; int aplwc_simulate_failure(void) { - aplwc_simulate_failure_count++; - if(aplwc_simulate_failure_at && (aplwc_simulate_failure_count >= aplwc_simulate_failure_at)) - return 1; - else - return 0; + unsigned long hits, start, count; + int fail; + + hits = aplwc_failsim_properties[APLWC_FAILSIM_HITS]++; + start = aplwc_failsim_query(APLWC_FAILSIM_START); + count = aplwc_failsim_query(APLWC_FAILSIM_COUNT); + + fail = (hits >= start) && (hits < start+count); + aplwc_failsim_properties[APLWC_FAILSIM_FAILS] += fail; + return fail; +} + +unsigned long +aplwc_failsim_query(enum aplwc_failsim_parameter p) +{ + return aplwc_failsim_properties[p]; +} + +static void +aplwc_failsim_init(unsigned long (*f)(enum aplwc_failsim_parameter, unsigned long)) +{ + enum aplwc_failsim_parameter p; + unsigned long v; + + for(p = 0; p < APLWC_FAILSIM_PARAMETER_COUNT; p++){ + switch(p){ + default: v = 0; break; + } + aplwc_failsim_properties[p] = f(p, v); + } } diff --git a/tests/Makefile.am b/tests/Makefile.am index 06d233d..16e1e8a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -63,7 +63,6 @@ TEST_SCRIPTS_SH += \ tests/scripts/bad/3.sh \ tests/scripts/bad/4.sh \ tests/scripts/bad/5.sh \ - tests/scripts/bad/6.sh \ tests/scripts/bad/7.sh TEST_SCRIPTS_APLWC += \ diff --git a/tests/run_script_test.sh b/tests/run_script_test.sh index cef7add..9e7d085 100755 --- a/tests/run_script_test.sh +++ b/tests/run_script_test.sh @@ -9,9 +9,17 @@ ext=${input##*.} check() { status=$1 + case $status in + 0|1) + ;; + *) + exit 99 + ;; + esac + case $expected in bad) - [ "$status" -ne 0 ] + [ "$status" -eq 1 ] ;; *) [ "$status" -eq 0 ] diff --git a/tests/run_simple_test.sh b/tests/run_simple_test.sh index 6c1d56c..e6ffc3e 100755 --- a/tests/run_simple_test.sh +++ b/tests/run_simple_test.sh @@ -11,11 +11,19 @@ expected=${input%%/*} "./testbin-$program" "$1" status=$? +case $status in + 0|1) + ;; + *) + exit 99 + ;; +esac + case $expected in good) [ "$status" -eq 0 ] ;; bad) - [ "$status" -ne 0 ] + [ "$status" -eq 1 ] ;; esac diff --git a/tests/scripts/bad/6.sh b/tests/scripts/bad/6.sh deleted file mode 100755 index 21fcc38..0000000 --- a/tests/scripts/bad/6.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -export APLWC_SIMULATE_FAILURE_PRINT_COUNT=1 -aplwc -x 3>&- diff --git a/tests/scripts/simfail.sh b/tests/scripts/simfail.sh index c10a7cb..75b97ab 100755 --- a/tests/scripts/simfail.sh +++ b/tests/scripts/simfail.sh @@ -1,20 +1,30 @@ #!/bin/sh -set -e +START=0 +COUNT=1 -export APLWC_SIMULATE_FAILURE_PRINT_COUNT=1 -N=$($1 3>&1 1>/dev/null 2>/dev/null) -n=1 -if [ -z "$N" ]; then - N=0 -fi - -export APLWC_SIMULATE_FAILURE_PRINT_COUNT=0 - -while [ "$n" -le "$N" ] +while true do - echo $n out of $N - export APLWC_SIMULATE_FAILURE_AT=$n - $1 #1>/dev/null 2>/dev/null - n=$((n + 1)) + echo "*** SIMFAIL (START=$START, COUNT=$COUNT) ***" + export APLWC_SIMULATE_FAILURE_START=$START + export APLWC_SIMULATE_FAILURE_COUNT=$COUNT + $1 + ret=$? + case $ret in + 99) + COUNT=$((COUNT + 1)) + ;; + 98) + COUNT=1 + START=$((START + 1)) + ;; + 0) + echo "*** SUCCESS ***" + exit 0 + ;; + *) + echo "*** FAILURE $ret ***" + exit $ret + ;; + esac done |