From 51181b9f13fe0b26135a448e2a5f3d4e4d82e151 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 18 Oct 2021 18:41:51 +0300 Subject: Code cleanups and bug fix. --- ChangeLog | 16 ++++++++++++++++ awkgram.c | 8 ++++---- awkgram.y | 8 ++++---- profile.c | 7 ++++--- symbol.c | 26 ++++++++++++++++++-------- test/ChangeLog | 5 +++++ test/Makefile.am | 6 ++++-- test/Makefile.in | 11 +++++++++-- test/Maketests | 5 +++++ test/profile16.awk | 16 ++++++++++++++++ test/profile16.ok | 18 ++++++++++++++++++ 11 files changed, 103 insertions(+), 23 deletions(-) create mode 100644 test/profile16.awk create mode 100644 test/profile16.ok diff --git a/ChangeLog b/ChangeLog index 8e4a5ec5..74c4e89a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2021-10-18 Arnold D. Robbins + + Factor duplicated code out into a separate function. + D.R.Y. principle. + + * symbol.c (get_name_from_awk_ns): New function. + (lookup): Use it. + (install): Use it. + + * awkgram.y (check_qualified_special): Use awk_namespace instead of a + string constant. + * profile.c (pprint): Ditto. + (adjust_namespace): Ditto. Also, fix the check for the qualified + name to look for the "::" in case one namespace is a prefix of + another. + 2021-10-13 Arnold D. Robbins * README: Update version, copyright year. diff --git a/awkgram.c b/awkgram.c index caa62a75..30c207e1 100644 --- a/awkgram.c +++ b/awkgram.c @@ -9273,8 +9273,8 @@ check_qualified_special(char *token) * Now it's more complicated. Here are the rules. * * 1. Namespace name cannot be a standard awk reserved word or function. - * 2. Subordinate part of the name cannot be standard awk reserved word or function. - * 3. If namespace part is explicitly "awk", return result of check_special(). + * 2. Subordinate part of the name cannot be a standard awk reserved word or function. + * 3. If the namespace part is explicitly "awk", return the result of check_special(). * 4. Else return -1 (gawk extensions allowed, we check standard awk in step 2). */ @@ -9306,12 +9306,12 @@ check_qualified_special(char *token) // Now check the subordinate part i = check_special(subname); - if (i >= 0 && (tokentab[i].flags & GAWKX) == 0 && strcmp(ns, "awk") != 0) { + if (i >= 0 && (tokentab[i].flags & GAWKX) == 0 && strcmp(ns, awk_namespace) != 0) { error_ln(sourceline, _("using reserved identifier `%s' as second component of a qualified name is not allowed"), subname); goto done; } - if (strcmp(ns, "awk") == 0) { + if (strcmp(ns, awk_namespace) == 0) { i = check_special(subname); if (i >= 0) { if ((tokentab[i].flags & GAWKX) != 0 && tokentab[i].class == LEX_BUILTIN) diff --git a/awkgram.y b/awkgram.y index 88bd2967..0729d353 100644 --- a/awkgram.y +++ b/awkgram.y @@ -6765,8 +6765,8 @@ check_qualified_special(char *token) * Now it's more complicated. Here are the rules. * * 1. Namespace name cannot be a standard awk reserved word or function. - * 2. Subordinate part of the name cannot be standard awk reserved word or function. - * 3. If namespace part is explicitly "awk", return result of check_special(). + * 2. Subordinate part of the name cannot be a standard awk reserved word or function. + * 3. If the namespace part is explicitly "awk", return the result of check_special(). * 4. Else return -1 (gawk extensions allowed, we check standard awk in step 2). */ @@ -6798,12 +6798,12 @@ check_qualified_special(char *token) // Now check the subordinate part i = check_special(subname); - if (i >= 0 && (tokentab[i].flags & GAWKX) == 0 && strcmp(ns, "awk") != 0) { + if (i >= 0 && (tokentab[i].flags & GAWKX) == 0 && strcmp(ns, awk_namespace) != 0) { error_ln(sourceline, _("using reserved identifier `%s' as second component of a qualified name is not allowed"), subname); goto done; } - if (strcmp(ns, "awk") == 0) { + if (strcmp(ns, awk_namespace) == 0) { i = check_special(subname); if (i >= 0) { if ((tokentab[i].flags & GAWKX) != 0 && tokentab[i].class == LEX_BUILTIN) diff --git a/profile.c b/profile.c index 3dd7bde9..c17d633c 100644 --- a/profile.c +++ b/profile.c @@ -647,7 +647,7 @@ cleanup: { const char *fname; if (pc->opcode == Op_builtin) { - bool prepend_awk = (current_namespace != awk_namespace && strcmp(current_namespace, "awk") != 0); + bool prepend_awk = (current_namespace != awk_namespace && strcmp(current_namespace, awk_namespace) != 0); fname = getfname(pc->builtin, prepend_awk); } else fname = (pc + 1)->func_name; @@ -2098,7 +2098,7 @@ adjust_namespace(char *name, bool *malloced) // unadorned name from symbol table, add awk:: if not in awk:: n.s. if (strchr(name, ':') == NULL && current_namespace != awk_namespace && // can be equal if namespace never changed - strcmp(current_namespace, "awk") != 0 && + strcmp(current_namespace, awk_namespace) != 0 && ! is_all_upper(name)) { char *buf; size_t len = 5 + strlen(name) + 1; @@ -2113,7 +2113,8 @@ adjust_namespace(char *name, bool *malloced) // qualifed name, remove :: if in that n.s. size_t len = strlen(current_namespace); - if (strncmp(current_namespace, name, len) == 0) { + if (strncmp(current_namespace, name, len) == 0 && + name[len] == ':' && name[len+1] == ':') { char *ret = name + len + 2; return ret; diff --git a/symbol.c b/symbol.c index 99a8b3a5..be01369c 100644 --- a/symbol.c +++ b/symbol.c @@ -39,6 +39,7 @@ static void (*install_func)(NODE *) = NULL; static NODE *make_symbol(const char *name, NODETYPE type); static NODE *install(const char *name, NODE *parm, NODETYPE type); static void free_bcpool(INSTRUCTION_POOL *pl); +static NODE *get_name_from_awk_ns(const char *name); static AWK_CONTEXT *curr_ctxt = NULL; static int ctxt_level; @@ -102,10 +103,7 @@ lookup(const char *name) tables[3] = symbol_table; /* then globals */ tables[4] = NULL; - if (strncmp(name, "awk::", 5) == 0) - tmp = make_string(name + 5, strlen(name) - 5); - else - tmp = make_string(name, strlen(name)); + tmp = get_name_from_awk_ns(name); n = NULL; for (i = 0; tables[i] != NULL; i++) { @@ -307,10 +305,7 @@ install(const char *name, NODE *parm, NODETYPE type) NODE *n_name; NODE *prev; - if (strncmp(name, "awk::", 5) == 0) - n_name = make_string(name + 5, strlen(name) - 5); - else - n_name = make_string(name, strlen(name)); + n_name = get_name_from_awk_ns(name); table = symbol_table; @@ -988,3 +983,18 @@ is_all_upper(const char *name) return true; } + +/* get_name_from_awk_ns --- get the name after awk:: or the full name */ + +static NODE * +get_name_from_awk_ns(const char *name) +{ + NODE *tmp; + + if (strncmp(name, "awk::", 5) == 0) + tmp = make_string(name + 5, strlen(name) - 5); + else + tmp = make_string(name, strlen(name)); + + return tmp; +} diff --git a/test/ChangeLog b/test/ChangeLog index 7af61551..7be3fc50 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2021-10-18 Arnold D. Robbins + + * Makefile.am (EXTRA_DIST): profile16, new test. + * profile16.awk, profile16.ok: New files. + 2021-10-13 Arnold D. Robbins * Gentest: Add check for ZOS_FAIL targets that have to diff --git a/test/Makefile.am b/test/Makefile.am index 1c20c6ea..547760b0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1009,6 +1009,8 @@ EXTRA_DIST = \ profile14.ok \ profile15.awk \ profile15.ok \ + profile16.awk \ + profile16.ok \ prt1eval.awk \ prt1eval.ok \ prtoeval.awk \ @@ -1453,7 +1455,7 @@ GAWK_EXT_TESTS = \ printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 \ profile7 profile8 profile9 profile10 profile11 profile12 profile13 \ - profile14 profile15 pty1 pty2 rebuf regexsub regnul1 regnul2 \ + profile14 profile15 profile16 pty1 pty2 rebuf regexsub regnul1 regnul2 \ regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ rsstart2 rsstart3 rstest6 sandbox1 shadow shadowbuiltin sortfor \ sortfor2 sortu sourcesplit split_after_fpat splitarg4 strftfld \ @@ -1515,7 +1517,7 @@ NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimpo # List of tests that need --pretty-print NEED_PRETTY = nsprof1 nsprof2 \ profile4 profile5 profile8 profile9 profile10 profile11 profile13 \ - profile14 profile15 + profile14 profile15 profile16 # List of tests that need --re-interval NEED_RE_INTERVAL = gsubtst3 reint reint2 diff --git a/test/Makefile.in b/test/Makefile.in index 0e228876..b265eabf 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1275,6 +1275,8 @@ EXTRA_DIST = \ profile14.ok \ profile15.awk \ profile15.ok \ + profile16.awk \ + profile16.ok \ prt1eval.awk \ prt1eval.ok \ prtoeval.awk \ @@ -1719,7 +1721,7 @@ GAWK_EXT_TESTS = \ printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 \ profile7 profile8 profile9 profile10 profile11 profile12 profile13 \ - profile14 profile15 pty1 pty2 rebuf regexsub regnul1 regnul2 \ + profile14 profile15 profile16 pty1 pty2 rebuf regexsub regnul1 regnul2 \ regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \ rsstart2 rsstart3 rstest6 sandbox1 shadow shadowbuiltin sortfor \ sortfor2 sortu sourcesplit split_after_fpat splitarg4 strftfld \ @@ -1780,7 +1782,7 @@ NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimpo # List of tests that need --pretty-print NEED_PRETTY = nsprof1 nsprof2 \ profile4 profile5 profile8 profile9 profile10 profile11 profile13 \ - profile14 profile15 + profile14 profile15 profile16 # List of tests that need --re-interval @@ -4824,6 +4826,11 @@ profile15: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --pretty-print=_$@ >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +profile16: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --pretty-print=_$@ >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + regexsub: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index c5c9104a..eb5e4bb3 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1891,6 +1891,11 @@ profile15: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --pretty-print=_$@ >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +profile16: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --pretty-print=_$@ >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + regexsub: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/profile16.awk b/test/profile16.awk new file mode 100644 index 00000000..e0c9c42b --- /dev/null +++ b/test/profile16.awk @@ -0,0 +1,16 @@ +BEGIN { + foo::foo_bar() + foofoo::xxx() +} + +@namespace "foo" + +function foo_bar() +{ + print "foo::foo_bar" +} + +function foofoo::xxx() +{ + print "foofoo::xxx" +} diff --git a/test/profile16.ok b/test/profile16.ok new file mode 100644 index 00000000..b954b1c5 --- /dev/null +++ b/test/profile16.ok @@ -0,0 +1,18 @@ +BEGIN { + foo::foo_bar() + foofoo::xxx() +} + + +@namespace "foo" + + +function foo_bar() +{ + print "foo::foo_bar" +} + +function foofoo::xxx() +{ + print "foofoo::xxx" +} -- cgit v1.2.3