diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | eval.c | 114 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 15 | ||||
-rw-r--r-- | test/Makefile.in | 21 | ||||
-rw-r--r-- | test/Maketests | 6 | ||||
-rw-r--r-- | test/posix_compare.awk | 47 | ||||
-rw-r--r-- | test/posix_compare.ok | 12 |
8 files changed, 157 insertions, 68 deletions
@@ -1,3 +1,8 @@ +2020-07-01 Arnold D. Robbins <arnold@skeeve.com> + + * eval.c (posix_compare): Rewrite contributed by + Michael Builov <mbuilov@gmail.com>. + 2020-06-29 Arnold D. Robbins <arnold@skeeve.com> * debug.c: Cleanup messages. Error messages start with lower @@ -503,79 +503,81 @@ genflags2str(int flagval, const struct flagtab *tab) static int posix_compare(NODE *s1, NODE *s2) { - int ret = 0; - char save1, save2; - size_t l = 0; + int ret; + + if (gawk_mb_cur_max == 1) { + char save1, save2; + const char *p1, *p2; - save1 = s1->stptr[s1->stlen]; - s1->stptr[s1->stlen] = '\0'; + save1 = s1->stptr[s1->stlen]; + s1->stptr[s1->stlen] = '\0'; - save2 = s2->stptr[s2->stlen]; - s2->stptr[s2->stlen] = '\0'; + save2 = s2->stptr[s2->stlen]; + s2->stptr[s2->stlen] = '\0'; - if (gawk_mb_cur_max == 1) { - if (strlen(s1->stptr) == s1->stlen && strlen(s2->stptr) == s2->stlen) - ret = strcoll(s1->stptr, s2->stptr); - else { - char b1[2], b2[2]; - char *p1, *p2; - size_t i; - - if (s1->stlen < s2->stlen) - l = s1->stlen; - else - l = s2->stlen; - - b1[1] = b2[1] = '\0'; - for (i = ret = 0, p1 = s1->stptr, p2 = s2->stptr; - ret == 0 && i < l; - p1++, p2++) { - b1[0] = *p1; - b2[0] = *p2; - ret = strcoll(b1, b2); + p1 = s1->stptr; + p2 = s2->stptr; + + for (;;) { + size_t len; + + ret = strcoll(p1, p2); + if (ret != 0) + break; + + len = strlen(p1); + p1 += len + 1; + p2 += len + 1; + + if (p1 == s1->stptr + s1->stlen + 1) { + if (p2 != s2->stptr + s2->stlen + 1) + ret = -1; + break; + } + if (p2 == s2->stptr + s2->stlen + 1) { + ret = 1; + break; } } - /* - * Either worked through the strings or ret != 0. - * In either case, ret will be the right thing to return. - */ + + s1->stptr[s1->stlen] = save1; + s2->stptr[s2->stlen] = save2; } #if ! defined(__DJGPP__) else { /* Similar logic, using wide characters */ + const wchar_t *p1, *p2; + (void) force_wstring(s1); (void) force_wstring(s2); - if (wcslen(s1->wstptr) == s1->wstlen && wcslen(s2->wstptr) == s2->wstlen) - ret = wcscoll(s1->wstptr, s2->wstptr); - else { - wchar_t b1[2], b2[2]; - wchar_t *p1, *p2; - size_t i; - - if (s1->wstlen < s2->wstlen) - l = s1->wstlen; - else - l = s2->wstlen; - - b1[1] = b2[1] = L'\0'; - for (i = ret = 0, p1 = s1->wstptr, p2 = s2->wstptr; - ret == 0 && i < l; - p1++, p2++) { - b1[0] = *p1; - b2[0] = *p2; - ret = wcscoll(b1, b2); + p1 = s1->wstptr; + p2 = s2->wstptr; + + for (;;) { + size_t len; + + ret = wcscoll(p1, p2); + if (ret != 0) + break; + + len = wcslen(p1); + p1 += len + 1; + p2 += len + 1; + + if (p1 == s1->wstptr + s1->wstlen + 1) { + if (p2 != s2->wstptr + s2->wstlen + 1) + ret = -1; + break; + } + if (p2 == s2->wstptr + s2->wstlen + 1) { + ret = 1; + break; } } - /* - * Either worked through the strings or ret != 0. - * In either case, ret will be the right thing to return. - */ } #endif - s1->stptr[s1->stlen] = save1; - s2->stptr[s2->stlen] = save2; return ret; } diff --git a/test/ChangeLog b/test/ChangeLog index 9b043559..bf033534 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2020-07-02 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (EXTRA_DIST): New test, posix_compare. + * posix_compare.awk, posix_compare.ok: New files. + 2020-06-29 Arnold D. Robbins <arnold@skeeve.com> * dbugeval2.ok, dbugtypedre1.ok, dbugtypedre2.ok, symtab10.ok, diff --git a/test/Makefile.am b/test/Makefile.am index 3c241aae..9be24a4c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -905,11 +905,13 @@ EXTRA_DIST = \ pipeio2.awk \ pipeio2.in \ pipeio2.ok \ + posix2008sub.awk \ + posix2008sub.ok \ + posix_compare.awk \ + posix_compare.ok \ posix.awk \ posix.in \ posix.ok \ - posix2008sub.awk \ - posix2008sub.ok \ poundbang.awk \ prdupval.awk \ prdupval.in \ @@ -1366,7 +1368,7 @@ BASIC_TESTS = \ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofmtstrnum ofs1 onlynl \ opasnidx opasnslf \ paramasfunc1 paramasfunc2 paramdup paramres paramtyp paramuninitglobal \ - parse1 parsefld parseme pcntplus posix2008sub prdupval prec printf0 \ + parse1 parsefld parseme pcntplus posix_compare posix2008sub prdupval prec printf0 \ printf1 printfchar prmarscl prmreuse prt1eval prtoeval \ rand randtest range1 range2 readbuf rebrackloc rebt8b1 rebuild redfilnm regeq \ regexpbrack regexpbrack2 regexprange regrange reindops reparse resplit \ @@ -1467,7 +1469,7 @@ NEED_MPFR = mpfrbigint mpfrbigint2 mpfrexprange mpfrfield mpfrieee mpfrmemok1 \ NEED_NONDEC = mpfrbigint2 nondec2 intarray forcenum # List of tests that need --posix -NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimposix +NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimposix posix_compare # List of tests that need --pretty-print NEED_PRETTY = nsprof1 nsprof2 \ @@ -1502,8 +1504,9 @@ NEED_LOCALE_C = \ NEED_LOCALE_EN = \ backbigs1 backsmalls1 backsmalls2 concat4 dfamb1 ignrcas2 lc_num1 \ - mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 printhuge reint2 \ - rri1 subamp subi18n wideidx wideidx2 widesub widesub2 widesub3 widesub4 + mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 posix_compare \ + printhuge reint2 rri1 subamp subi18n wideidx wideidx2 \ + widesub widesub2 widesub3 widesub4 # Unused at the moment, since nlstringtest has additional stufff it does # NEED_LOCALE_FR = diff --git a/test/Makefile.in b/test/Makefile.in index c4b72106..fae611a4 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1168,11 +1168,13 @@ EXTRA_DIST = \ pipeio2.awk \ pipeio2.in \ pipeio2.ok \ + posix2008sub.awk \ + posix2008sub.ok \ + posix_compare.awk \ + posix_compare.ok \ posix.awk \ posix.in \ posix.ok \ - posix2008sub.awk \ - posix2008sub.ok \ poundbang.awk \ prdupval.awk \ prdupval.in \ @@ -1629,7 +1631,7 @@ BASIC_TESTS = \ octsub ofmt ofmta ofmtbig ofmtfidl ofmts ofmtstrnum ofs1 onlynl \ opasnidx opasnslf \ paramasfunc1 paramasfunc2 paramdup paramres paramtyp paramuninitglobal \ - parse1 parsefld parseme pcntplus posix2008sub prdupval prec printf0 \ + parse1 parsefld parseme pcntplus posix_compare posix2008sub prdupval prec printf0 \ printf1 printfchar prmarscl prmreuse prt1eval prtoeval \ rand randtest range1 range2 readbuf rebrackloc rebt8b1 rebuild redfilnm regeq \ regexpbrack regexpbrack2 regexprange regrange reindops reparse resplit \ @@ -1729,7 +1731,7 @@ NEED_MPFR = mpfrbigint mpfrbigint2 mpfrexprange mpfrfield mpfrieee mpfrmemok1 \ NEED_NONDEC = mpfrbigint2 nondec2 intarray forcenum # List of tests that need --posix -NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimposix +NEED_POSIX = escapebrace printf0 posix2008sub paramasfunc1 paramasfunc2 muldimposix posix_compare # List of tests that need --pretty-print NEED_PRETTY = nsprof1 nsprof2 \ @@ -1767,8 +1769,9 @@ NEED_LOCALE_C = \ NEED_LOCALE_EN = \ backbigs1 backsmalls1 backsmalls2 concat4 dfamb1 ignrcas2 lc_num1 \ - mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 printhuge reint2 \ - rri1 subamp subi18n wideidx wideidx2 widesub widesub2 widesub3 widesub4 + mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 posix_compare \ + printhuge reint2 rri1 subamp subi18n wideidx wideidx2 \ + widesub widesub2 widesub3 widesub4 # Unused at the moment, since nlstringtest has additional stufff it does @@ -3672,6 +3675,12 @@ pcntplus: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +posix_compare: + @echo $@ + @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; export GAWKLOCALE; \ + AWKPATH="$(srcdir)" $(AWK) -f $@.awk --posix >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + posix2008sub: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --posix >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 1c54a7cf..f7aaa152 100644 --- a/test/Maketests +++ b/test/Maketests @@ -798,6 +798,12 @@ pcntplus: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +posix_compare: + @echo $@ + @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; export GAWKLOCALE; \ + AWKPATH="$(srcdir)" $(AWK) -f $@.awk --posix >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + posix2008sub: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk --posix >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/posix_compare.awk b/test/posix_compare.awk new file mode 100644 index 00000000..dcef124d --- /dev/null +++ b/test/posix_compare.awk @@ -0,0 +1,47 @@ +function print_str(str, i, n, chars, result) +{ + n = split(str, chars, "") + result = "" + for (i = 1; i <= n; i++) { + if (chars[i] == "\0") + result = result "\\0" + else + result = result chars[i] + } + + return result +} + +function do_compare(left, comp, right) +{ + if (comp == "<") + return left < right ? "TRUE" : "FALSE" + + return left > right ? "TRUE" : "FALSE" +} + + +BEGIN { + left[1] = "abc\0z1"; compare[1] = "<"; right[1] = "abc\0z2"; expected[1] = "TRUE" + left[2] = "abc\0z2"; compare[2] = "<"; right[2] = "abc\0z2"; expected[2] = "FALSE" + left[3] = "abc\0z3"; compare[3] = "<"; right[3] = "abc\0z2"; expected[3] = "FALSE" + left[4] = "abc\0z1"; compare[4] = ">"; right[4] = "abc\0z2"; expected[4] = "FALSE" + left[5] = "abc\0z2"; compare[5] = ">"; right[5] = "abc\0z2"; expected[5] = "FALSE" + left[6] = "abc\0z3"; compare[6] = ">"; right[6] = "abc\0z2"; expected[6] = "TRUE" + left[7] = "abc\0z1"; compare[7] = "<"; right[7] = "abc\0z21"; expected[7] = "TRUE" + left[8] = "abc\0z2"; compare[8] = "<"; right[8] = "abc\0z21"; expected[8] = "TRUE" + left[9] = "abc\0z3"; compare[9] = "<"; right[9] = "abc\0z21"; expected[9] = "FALSE" + left[10] = "abc\0z11"; compare[10] = ">"; right[10] = "abc\0z2"; expected[10] = "FALSE" + left[11] = "abc\0z21"; compare[11] = ">"; right[11] = "abc\0z2"; expected[11] = "TRUE" + left[12] = "abc\0z31"; compare[12] = ">"; right[12] = "abc\0z2"; expected[12] = "TRUE" + + l = 12 + for (i = 1; i <= l; i++) { + result = do_compare(left[i], compare[i], right[i]) + lstr = print_str(left[i]) + rstr = print_str(right[i]) + + printf("\"%s\" %s \"%s\": Expecting %s: Got %s\n", + lstr, compare[i], rstr, expected[i], result) + } +} diff --git a/test/posix_compare.ok b/test/posix_compare.ok new file mode 100644 index 00000000..58dee56b --- /dev/null +++ b/test/posix_compare.ok @@ -0,0 +1,12 @@ +"abc\0z1" < "abc\0z2": Expecting TRUE: Got TRUE +"abc\0z2" < "abc\0z2": Expecting FALSE: Got FALSE +"abc\0z3" < "abc\0z2": Expecting FALSE: Got FALSE +"abc\0z1" > "abc\0z2": Expecting FALSE: Got FALSE +"abc\0z2" > "abc\0z2": Expecting FALSE: Got FALSE +"abc\0z3" > "abc\0z2": Expecting TRUE: Got TRUE +"abc\0z1" < "abc\0z21": Expecting TRUE: Got TRUE +"abc\0z2" < "abc\0z21": Expecting TRUE: Got TRUE +"abc\0z3" < "abc\0z21": Expecting FALSE: Got FALSE +"abc\0z11" > "abc\0z2": Expecting FALSE: Got FALSE +"abc\0z21" > "abc\0z2": Expecting TRUE: Got TRUE +"abc\0z31" > "abc\0z2": Expecting TRUE: Got TRUE |