summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/main.c14
-rw-r--r--src/lib/aplwc_internal.h3
-rw-r--r--src/lib/main.c2
-rw-r--r--src/lib/module.c46
-rw-r--r--src/lib/syntax.c48
-rw-r--r--tests/Makefile.am8
-rwxr-xr-xtests/run_script_test.sh9
-rwxr-xr-xtests/scripts/bad/1.aplwc1
-rwxr-xr-xtests/scripts/bad/2.aplwc1
-rwxr-xr-xtests/scripts/bad/3.aplwc1
-rwxr-xr-xtests/scripts/bad/6.aplwc1
-rwxr-xr-xtools/check2
-rwxr-xr-xtools/checkcov2
13 files changed, 83 insertions, 55 deletions
diff --git a/src/bin/main.c b/src/bin/main.c
index a969956..5242cd5 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -92,7 +92,9 @@ main(int argc, char *argv[])
int opt, xflag, input_file;
long tmp;
FILE *f;
- unsigned long failsim_count, failsim_fails;
+ unsigned long failsim_count, failsim_fails, failsim_strict;
+
+ failsim_strict = getenv_ulong("APLWC_FAILSIM_STRICT", 0);
aplwc_clear_line(&line);
aplwc_clear_value(&value);
@@ -208,7 +210,7 @@ file_size:
if(!aplwc_valid_line(&line)){
line_error:
fprintf(stderr, "error on line %d: %s: %s\n", line_number, aplwc_errstr(aplwc), input);
- if(aplwc_failsim_query(APLWC_FAILSIM_COUNT) > 0){
+ if(failsim_strict){
ret = aplwc_last_error(aplwc);
goto end;
}else
@@ -224,7 +226,7 @@ line_error:
end:
if(input)
free(input);
- if(NEVER(aplwc_valid_line(&line)))
+ if(aplwc_valid_line(&line))
aplwc_free_line(&line);
if(NEVER(aplwc_valid_value(&value)))
aplwc_free_value(&value);
@@ -233,14 +235,16 @@ end:
failsim_count = aplwc_failsim_query(APLWC_FAILSIM_COUNT);
failsim_fails = aplwc_failsim_query(APLWC_FAILSIM_FAILS);
- if(failsim_count > 0){
+ if(failsim_fails > 0){
switch(ret){
case APLWC_OK:
case APLWC_OTHER_FAILURE:
case APLWC_OUT_OF_MEMORY:
break;
default:
- return 97;
+ if(failsim_strict)
+ return 97;
+ break;
}
if(failsim_count > failsim_fails)
diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h
index c123d63..ca7e719 100644
--- a/src/lib/aplwc_internal.h
+++ b/src/lib/aplwc_internal.h
@@ -171,7 +171,7 @@ struct string *substring(struct aplwc *, struct string *, size_t, size_t);
/* syntax.c */
struct token_list *scan_string(struct aplwc *, struct string *, int);
-enum aplwc_rc check_tokens(struct aplwc_module *, struct token_list *);
+enum aplwc_rc check_tokens(struct aplwc *, struct aplwc_module *, struct token_list *);
enum aplwc_rc keyword_init(struct aplwc *);
/* symtab.c */
@@ -179,6 +179,7 @@ enum aplwc_rc getsym(struct aplwc *, struct string *, symbol_t *);
/* module.c */
enum aplwc_rc load_module(struct aplwc *, struct string *, struct token_list *);
+struct aplwc_module *module_lookup(struct aplwc *, struct string *);
/* unicode.c */
int is_id_start(uint32_t);
diff --git a/src/lib/main.c b/src/lib/main.c
index 6cfff40..e182a9e 100644
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -131,7 +131,7 @@ aplwc_read(struct aplwc *aplwc, const char *linestr, AplwcLine *lineptr)
goto end;
MEMPTR(1, tokens);
- if((aplwc->last_error = check_tokens(NULL, tokens)) != APLWC_OK)
+ if((aplwc->last_error = check_tokens(aplwc, NULL, tokens)) != APLWC_OK)
goto end;
if((line = memory_alloc_aplwc_line(aplwc)) == NULL)
diff --git a/src/lib/module.c b/src/lib/module.c
index aaa9634..9c2cbc2 100644
--- a/src/lib/module.c
+++ b/src/lib/module.c
@@ -72,20 +72,20 @@ read_keyword_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offse
switch(t(0).data.keyword){
case KW_MODULE:
if((max < 1) || (t(1).tag != TOKEN_TAG_IDENTIFIER))
- goto fail;
+ goto fail_syntax;
len = 1;
break;
case KW_SYMBOL:
if((max < 1) || (t(1).tag != TOKEN_TAG_IDENTIFIER))
- goto fail;
+ goto fail_syntax;
if((max < 2) || (t(2).tag != TOKEN_TAG_UNKNOWN_SYM))
- goto fail;
+ goto fail_syntax;
len = 2;
if((m = add_member(aplwc, module, t(1).data.symbol, NULL, 0)) == NULL)
- goto fail;
+ goto fail_other;
if(add_member(aplwc, module, t(2).data.symbol, m, 0) == NULL)
- goto fail;
+ goto fail_other;
break;
case KW_EXPORT:
for(len = 1; (size_t)len < max; len++){
@@ -93,12 +93,14 @@ read_keyword_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offse
case TOKEN_TAG_UNKNOWN_SYM:
case TOKEN_TAG_IDENTIFIER:
if(add_member(aplwc, module, t(len).data.symbol, NULL, 1) == NULL)
- goto fail;
+ goto fail_other;
break;
case TOKEN_TAG_NEWLINE:
goto end;
default:
-fail:
+fail_syntax:
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+fail_other:
len = -1;
goto end;
}
@@ -108,7 +110,7 @@ fail:
if(ALWAYS(len >= 0) && (max > (size_t)len))
if(t(len+1).tag != TOKEN_TAG_NEWLINE)
- goto fail;
+ goto fail_syntax;
len++; /* For the keyword itself */
end:
MEMPTRS_EXIT(aplwc);
@@ -117,7 +119,7 @@ end:
}
static int
-read_function_decl(struct aplwc_module *module, size_t offset)
+read_function_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offset)
{
int len, ok;
@@ -128,7 +130,11 @@ read_function_decl(struct aplwc_module *module, size_t offset)
break;
}
}
- return ok ? len : -1;
+ if(!ok){
+ len = -1;
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+ }
+ return len;
}
static int
@@ -141,8 +147,9 @@ read_decl(struct aplwc *aplwc, struct aplwc_module *module, size_t offset)
case TOKEN_TAG_KEYWORD:
return read_keyword_decl(aplwc, module, offset);
case TOKEN_TAG_DEL:
- return read_function_decl(module, offset);
+ return read_function_decl(aplwc, module, offset);
default:
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
return -1;
}
}
@@ -152,27 +159,23 @@ read_decls(struct aplwc *aplwc, struct aplwc_module *module)
{
size_t offset;
int skip;
- enum aplwc_rc rc;
MEMPTRS(aplwc, 1);
MEMPTR(0, module);
- rc = APLWC_OK;
for(offset = 0; offset < module->tokens->length; offset++){
skip = read_decl(aplwc, module, offset);
- if(skip == -1){
- rc = APLWC_INVALID_SYNTAX;
+ if(skip == -1)
goto end;
- }
offset += skip;
}
end:
MEMPTRS_EXIT(aplwc);
- return rc;
+ return aplwc->last_error;
}
-static struct aplwc_module *
+struct aplwc_module *
module_lookup(struct aplwc *aplwc, struct string *name)
{
struct aplwc_module *m;
@@ -193,7 +196,7 @@ resolve_imports(struct aplwc *aplwc, struct aplwc_module *module)
struct module_member *m;
enum aplwc_rc rc;
- MEMPTRS(aplwc, 1);
+ MEMPTRS(aplwc, 3);
MEMPTR(0, module);
rc = APLWC_OK;
@@ -204,6 +207,9 @@ resolve_imports(struct aplwc *aplwc, struct aplwc_module *module)
if((imported = module_lookup(aplwc, name)) == NULL)
goto end; /* only because it is Boot for now... */
+ MEMPTR(1, imported);
+ m = NULL;
+ MEMPTR(2, m);
for(m = imported->members; m; m = m->link){
if(m->exported == 0)
@@ -244,7 +250,7 @@ load_module(struct aplwc *aplwc, struct string *name, struct token_list *tokens)
if((aplwc->last_error = resolve_imports(aplwc, module)) != APLWC_OK)
goto end;
- if((aplwc->last_error = check_tokens(module, tokens)) != APLWC_OK)
+ if((aplwc->last_error = check_tokens(aplwc, module, tokens)) != APLWC_OK)
goto end;
module->link = aplwc->modules;
diff --git a/src/lib/syntax.c b/src/lib/syntax.c
index d864bf4..3354050 100644
--- a/src/lib/syntax.c
+++ b/src/lib/syntax.c
@@ -446,7 +446,6 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline)
for(i++; i < n; i++){
if(tokens->tokens[i].tag != TOKEN_TAG_NEWLINE){
rc = APLWC_INVALID_SYNTAX;
- tokens = NULL;
goto end;
}
}
@@ -454,27 +453,40 @@ scan_string(struct aplwc *aplwc, struct string *text, int oneline)
end:
aplwc->last_error = rc;
+ if(aplwc->last_error != APLWC_OK)
+ tokens = NULL;
MEMPTRS_EXIT(aplwc);
return tokens;
}
static void
-resolve_unknown(struct aplwc_module *module, struct token *t)
+resolve_unknown(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens, size_t i)
{
symbol_t s;
struct module_member *m;
+ struct string *boot;
- assert(t && (t->tag == TOKEN_TAG_UNKNOWN_SYM));
- if(module == NULL)
- return;
+ MEMPTRS(aplwc, 3);
+ MEMPTR(0, module);
+ MEMPTR(1, tokens);
+
+ assert(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM);
+ if(module == NULL){
+ /* Try to look into the Boot module */
+ if((boot = chars_to_string(aplwc, "Boot", -1)) == NULL)
+ goto end;
+ MEMPTR(2, boot);
+ if((module = module_lookup(aplwc, boot)) == NULL)
+ goto end;
+ }
- s = t->data.symbol;
+ s = tokens->tokens[i].data.symbol;
for(m = module->members; m; m = m->link){
if(m->name == s){
found:
- t->tag = TOKEN_TAG_IDENTIFIER;
- return;
+ tokens->tokens[i].tag = TOKEN_TAG_IDENTIFIER;
+ goto end;
}
}
@@ -482,27 +494,35 @@ found:
if(m->name == s)
goto found;
}
+
+ aplwc->last_error = APLWC_INVALID_SYNTAX;
+end:
+ MEMPTRS_EXIT(aplwc);
}
enum aplwc_rc
-check_tokens(struct aplwc_module *module, struct token_list *tokens)
+check_tokens(struct aplwc *aplwc, struct aplwc_module *module, struct token_list *tokens)
{
size_t i;
- enum aplwc_rc rc;
- for(i = 0, rc = APLWC_OK; (rc == APLWC_OK) && (i < tokens->length); i++){
+ MEMPTRS(aplwc, 2);
+ MEMPTR(0, module);
+ MEMPTR(1, tokens);
+
+ for(i = 0, aplwc->last_error = APLWC_OK; (aplwc->last_error == APLWC_OK) && (i < tokens->length); i++){
switch(tokens->tokens[i].tag){
case TOKEN_TAG_UNKNOWN_SYM:
- resolve_unknown(module, &tokens->tokens[i]);
+ resolve_unknown(aplwc, module, tokens, i);
if(tokens->tokens[i].tag == TOKEN_TAG_UNKNOWN_SYM)
- return APLWC_INVALID_SYNTAX;
+ assert(aplwc->last_error != APLWC_OK);
break;
default:
break;
}
}
- return rc;
+ MEMPTRS_EXIT(aplwc);
+ return aplwc->last_error;
}
enum aplwc_rc
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 16e1e8a..bea1bac 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -71,12 +71,8 @@ TEST_SCRIPTS_APLWC += \
tests/scripts/good/3.aplwc
TEST_SCRIPTS_APLWC += \
- tests/scripts/bad/1.aplwc \
- tests/scripts/bad/2.aplwc \
- tests/scripts/bad/3.aplwc \
tests/scripts/bad/4.aplwc \
tests/scripts/bad/5.aplwc \
- tests/scripts/bad/6.aplwc \
tests/scripts/bad/7.aplwc \
tests/scripts/bad/8.aplwc \
tests/scripts/bad/9.aplwc \
@@ -84,7 +80,3 @@ TEST_SCRIPTS_APLWC += \
tests/scripts/bad/11.aplwc \
tests/scripts/bad/12.aplwc \
tests/scripts/bad/13.aplwc
-
-XFAIL_TESTS += \
- tests/scripts/bad/1.aplwc \
- tests/scripts/bad/3.aplwc
diff --git a/tests/run_script_test.sh b/tests/run_script_test.sh
index 9e7d085..a6ccfa8 100755
--- a/tests/run_script_test.sh
+++ b/tests/run_script_test.sh
@@ -30,6 +30,15 @@ check()
fi
}
+case $expected in
+ good)
+ export APLWC_FAILSIM_STRICT=1
+ ;;
+ bad)
+ export APLWC_FAILSIM_STRICT=0
+ ;;
+esac
+
"$1"
check $?
diff --git a/tests/scripts/bad/1.aplwc b/tests/scripts/bad/1.aplwc
deleted file mode 100755
index 792d600..0000000
--- a/tests/scripts/bad/1.aplwc
+++ /dev/null
@@ -1 +0,0 @@
-#
diff --git a/tests/scripts/bad/2.aplwc b/tests/scripts/bad/2.aplwc
deleted file mode 100755
index 1e0a14c..0000000
--- a/tests/scripts/bad/2.aplwc
+++ /dev/null
@@ -1 +0,0 @@
-!#
diff --git a/tests/scripts/bad/3.aplwc b/tests/scripts/bad/3.aplwc
deleted file mode 100755
index ba38a01..0000000
--- a/tests/scripts/bad/3.aplwc
+++ /dev/null
@@ -1 +0,0 @@
-##
diff --git a/tests/scripts/bad/6.aplwc b/tests/scripts/bad/6.aplwc
deleted file mode 100755
index dd21832..0000000
--- a/tests/scripts/bad/6.aplwc
+++ /dev/null
@@ -1 +0,0 @@
-#!/bla/bla \ No newline at end of file
diff --git a/tools/check b/tools/check
index a3ad0ab..63a5c6d 100755
--- a/tools/check
+++ b/tools/check
@@ -31,7 +31,7 @@ do
;;
esac
../../configure --enable-maintainer-mode --enable-build-mode=$type CFLAGS="$CFLAGS -Wall -Wextra -Werror -std=c89 -pedantic" $OTHER
- make check
+ make -j check
../../configure --enable-maintainer-mode --enable-build-mode=$type CFLAGS="$CFLAGS" $OTHER
cd ..
done
diff --git a/tools/checkcov b/tools/checkcov
index 412a58e..5798dfb 100755
--- a/tools/checkcov
+++ b/tools/checkcov
@@ -13,7 +13,7 @@ case "$1" in
;;
esac
-make check
+make -j check
case "$1" in
coverage)