summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/main.c75
-rw-r--r--src/include/aplwc.h15
-rw-r--r--src/include/aplwc_macros.h1
-rw-r--r--src/lib/main.c46
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/run_script_test.sh10
-rwxr-xr-xtests/run_simple_test.sh10
-rwxr-xr-xtests/scripts/bad/6.sh4
-rwxr-xr-xtests/scripts/simfail.sh40
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