diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 61005019..f167f71a 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -96,8 +96,19 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) return ASE_NULL; } + if (ase_awk_tab_open (&awk->parse.afns, awk) == ASE_NULL) + { + ase_awk_map_close (awk->tree.afns); + ase_awk_map_close (awk->rwtab); + ase_awk_map_close (awk->wtab); + ase_str_close (&awk->token.name); + ASE_AWK_FREE (awk, awk); + return ASE_NULL; + } + if (ase_awk_tab_open (&awk->parse.globals, awk) == ASE_NULL) { + ase_awk_tab_close (&awk->parse.afns); ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); @@ -109,6 +120,7 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) if (ase_awk_tab_open (&awk->parse.locals, awk) == ASE_NULL) { ase_awk_tab_close (&awk->parse.globals); + ase_awk_tab_close (&awk->parse.afns); ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); @@ -121,6 +133,7 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) { ase_awk_tab_close (&awk->parse.locals); ase_awk_tab_close (&awk->parse.globals); + ase_awk_tab_close (&awk->parse.afns); ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); @@ -168,6 +181,7 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) ase_awk_tab_close (&awk->parse.params); ase_awk_tab_close (&awk->parse.locals); ase_awk_tab_close (&awk->parse.globals); + ase_awk_tab_close (&awk->parse.afns); ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); @@ -195,6 +209,7 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) ase_awk_tab_close (&awk->parse.params); ase_awk_tab_close (&awk->parse.locals); ase_awk_tab_close (&awk->parse.globals); + ase_awk_tab_close (&awk->parse.afns); ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); @@ -239,9 +254,12 @@ int ase_awk_close (ase_awk_t* awk) ase_awk_tab_close (&awk->parse.params); ase_awk_tab_close (&awk->parse.locals); ase_awk_tab_close (&awk->parse.globals); + ase_awk_tab_close (&awk->parse.afns); + ase_awk_map_close (awk->tree.afns); ase_awk_map_close (awk->rwtab); ase_awk_map_close (awk->wtab); + ase_str_close (&awk->token.name); for (i = 0; i < ASE_COUNTOF(awk->errstr); i++) @@ -279,6 +297,7 @@ int ase_awk_clear (ase_awk_t* awk) ase_awk_tab_clear (&awk->parse.locals); ase_awk_tab_clear (&awk->parse.params); + ase_awk_tab_clear (&awk->parse.afns); awk->parse.nlocals_max = 0; awk->parse.depth.cur.block = 0; diff --git a/ase/awk/awk.h b/ase/awk/awk.h index c53adeaa..488ffa5e 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -159,8 +159,8 @@ enum ase_awk_option_t /* allow undeclared variables and implicit concatenation */ ASE_AWK_IMPLICIT = (1 << 0), - /* allow explicit variable declaration and the concatenation - * operator, a period. */ + /* allow explicit variable declaration, the concatenation + * operator(.), and a parse-time function check. */ ASE_AWK_EXPLICIT = (1 << 1), /* a function name should not coincide to be a variable name */ diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 70f9d540..91210ad7 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -117,13 +117,24 @@ struct ase_awk_t } max; } depth; + /* function calls */ + ase_awk_tab_t afns; + + /* global variables */ ase_awk_tab_t globals; + + /* local variables */ ase_awk_tab_t locals; + + /* parameters to a function */ ase_awk_tab_t params; + + /* maximum number of local variables */ ase_size_t nlocals_max; ase_awk_nde_t* (*parse_block) ( ase_awk_t*,ase_size_t,ase_bool_t); + } parse; /* source code management */ @@ -171,7 +182,6 @@ struct ase_awk_t struct { ase_awk_bfn_t* sys; - /*ase_awk_bfn_t* user;*/ ase_awk_map_t* user; } bfn; diff --git a/ase/awk/parse.c b/ase/awk/parse.c index d99d8f33..53cef365 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -519,9 +519,30 @@ static int parse (ase_awk_t* awk) goto exit_parse; } } + + if (awk->option & ASE_AWK_EXPLICIT) + { + ase_size_t sz; + + sz = awk->parse.afns.size; + while (sz > 0) + { + sz--; + + if (ase_awk_map_get (awk->tree.afns, + awk->parse.afns.buf[sz].name.ptr, + awk->parse.afns.buf[sz].name.len) == ASE_NULL) + { + /* TODO: set proper error number */ + SETERR (awk, ASE_AWK_EINVAL); + n = -1; + goto exit_parse; + } + } + } } - ASE_ASSERT (awk->tree.nglobals == ase_awk_tab_getsize(&awk->parse.globals)); + ASE_ASSERT (awk->tree.nglobals == awk->parse.globals.size); if (awk->src.ios.out != ASE_NULL) { @@ -1421,8 +1442,7 @@ static int add_global ( } /* check if it conflict with a function name */ - if (ase_awk_map_get ( - awk->tree.afns, name, len) != ASE_NULL) + if (ase_awk_map_get (awk->tree.afns, name, len) != ASE_NULL) { SETERRARG ( awk, ASE_AWK_EAFNRED, line, @@ -3129,7 +3149,7 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) } /* check if it is an AWK function */ - if (ase_awk_map_get(awk->tree.afns, name_dup, name_len) != ASE_NULL) + if (ase_awk_map_get (awk->tree.afns, name_dup, name_len) != ASE_NULL) { /* the function is defined previously */ SETERRARG (awk, ASE_AWK_EAFNRED, line, name_dup, name_len); @@ -3282,7 +3302,7 @@ static ase_awk_nde_t* parse_hashidx ( } /* check if it is an AWK function */ - if (ase_awk_map_get(awk->tree.afns, name, name_len) != ASE_NULL) + if (ase_awk_map_get (awk->tree.afns, name, name_len) != ASE_NULL) { /* the function is defined previously */ SETERRARG (awk, ASE_AWK_EAFNRED, line, name, name_len); @@ -3422,6 +3442,15 @@ static ase_awk_nde_t* parse_fncall ( call->what.afn.name.len = name_len; call->args = head; call->nargs = nargs; + + if ((awk->option & ASE_AWK_EXPLICIT) && + ase_awk_tab_adduniq (&awk->parse.afns, name, name_len) == (ase_size_t)-1) + { + ASE_AWK_FREE (awk, call); + if (head != ASE_NULL) ase_awk_clrpt (awk, head); + SETERRLIN (awk, ASE_AWK_ENOMEM, line); + return ASE_NULL; + } } return (ase_awk_nde_t*)call; diff --git a/ase/awk/tab.c b/ase/awk/tab.c index 6fd3706d..2df4d291 100644 --- a/ase/awk/tab.c +++ b/ase/awk/tab.c @@ -186,6 +186,17 @@ ase_size_t ase_awk_tab_add ( return ase_awk_tab_insert (tab, tab->size, str, len); } +ase_size_t ase_awk_tab_adduniq ( + ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len) +{ + ase_size_t i; + i = ase_awk_tab_find (tab, 0, str, len); + if (i != (ase_size_t)-1) return i; /* found. return the current index */ + + /* insert a new entry */ + return ase_awk_tab_insert (tab, tab->size, str, len); +} + ase_size_t ase_awk_tab_find ( ase_awk_tab_t* tab, ase_size_t index, const ase_char_t* str, ase_size_t len) diff --git a/ase/awk/tab.h b/ase/awk/tab.h index a2a071fa..d7462865 100644 --- a/ase/awk/tab.h +++ b/ase/awk/tab.h @@ -54,6 +54,8 @@ ase_size_t ase_awk_tab_remove ( ase_size_t ase_awk_tab_add ( ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len); +ase_size_t ase_awk_tab_adduniq ( + ase_awk_tab_t* tab, const ase_char_t* str, ase_size_t len); ase_size_t ase_awk_tab_find ( ase_awk_tab_t* tab, ase_size_t index, diff --git a/ase/rel/doc.awk b/ase/rel/doc.awk index 18f15a37..eccf91c0 100644 --- a/ase/rel/doc.awk +++ b/ase/rel/doc.awk @@ -9,7 +9,7 @@ global empty_line_count; global para_started; global list_count; -func print_text (full) +function print_text (full) { local fra1, fra2, link, idx, t1, t2; diff --git a/ase/rel/rel.sh b/ase/rel/rel.sh index 1b2c8b71..c370b2b5 100755 --- a/ase/rel/rel.sh +++ b/ase/rel/rel.sh @@ -44,12 +44,12 @@ finalize () case "$i" in *.h|*.c|*.cc|*.cpp|*.java|*.awk|*.in) - "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/lic.awk" -a "$target/$file" "$full" + "$ASEAWK" -f "$BASE/rel/lic.awk" -a "$target/$file" "$full" ;; *.man) html=`echo $i | sed 's/.man$/.html/'` "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/doc.awk" "$full" > "$SOURCE_ROOT/html/$html" - "$ASEAWK" -explicit -f "$BASE/rel/doc.awk" "$full" > "$ASETGT/$html" + "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/doc.awk" "$full" > "$ASETGT/$html" cp -f "$full" "$target/$file" ;; *.css) @@ -58,10 +58,10 @@ finalize () cp -f "$full" "$ASETGT/$i" ;; *.dsp|*.dsw|*.sln|*.vcproj|*.csproj|*.bat|*.cmd) - "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" + "$ASEAWK" -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" ;; descrip.mms) - "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" + "$ASEAWK" -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" ;; *.frx) cp -f "$full" "$target/$file" @@ -69,7 +69,7 @@ finalize () *) if [ "$dir" = "test/com" ] then - "$ASEAWK" -explicit -noimplicit -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" + "$ASEAWK" -f "$BASE/rel/unix2dos.awk" "$full" > "$target/$file" else cp -f "$full" "$target/$file" fi