gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] gawk branch, feature/iolint, created. gawk-4.1.0-4122-g55eee61


From: Arnold Robbins
Subject: [SCM] gawk branch, feature/iolint, created. gawk-4.1.0-4122-g55eee61
Date: Mon, 21 Sep 2020 10:06:45 -0400 (EDT)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, feature/iolint has been created
        at  55eee619ac637e29c0fe847cc89cda78cc18c28d (commit)

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=55eee619ac637e29c0fe847cc89cda78cc18c28d

commit 55eee619ac637e29c0fe847cc89cda78cc18c28d
Author: Arnold D. Robbins <arnold@skeeve.com>
Date:   Mon Sep 21 17:02:23 2020 +0300

    Add lint checks for same redirection used multiple ways.

diff --git a/ChangeLog b/ChangeLog
index e5e1f36..dacc02a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-09-21         Arnold D. Robbins     <arnold@skeeve.com>
+
+       * awk.h (enum redirect_flags): Add RED_NONE.
+       (redirect_flags_t): New typedef.
+       * io.c (redflags2str): Handle RED_NONE.
+       (check_duplicated_redirections): New function.
+       (redirect_string): Use new typedef. Call new function if do_lint
+       instead of using inline code.
+       (close_redir): Add error message for failure on close of two-way pipe.
+
 2020-09-04         Arnold D. Robbins     <arnold@skeeve.com>
 
        * awkgram.y [GRAMMAR]: Install arrays as Node_var_array. Improves
diff --git a/awk.h b/awk.h
index c2218cd..cf06d49 100644
--- a/awk.h
+++ b/awk.h
@@ -957,6 +957,7 @@ typedef void (*Func_ptr)(void);
 /* structure used to dynamically maintain a linked-list of open files/pipes */
 struct redirect {
        enum redirect_flags {
+               RED_NONE        = 0,
                RED_FILE        = 1,
                RED_PIPE        = 2,
                RED_READ        = 4,
@@ -980,6 +981,7 @@ struct redirect {
        const char *mode;
        awk_output_buf_t output;
 };
+typedef enum redirect_flags redirect_flags_t;
 
 /* values for BINMODE, used as bit flags */
 
diff --git a/io.c b/io.c
index 2478f0c..1fb9587 100644
--- a/io.c
+++ b/io.c
@@ -725,9 +725,72 @@ redflags2str(int flags)
                { 0, NULL }
        };
 
+       if (flags == RED_NONE)
+               return "RED_NONE";
+
        return genflags2str(flags, redtab);
 }
 
+/* check_duplicated_redirections --- see if the same name used differently */
+
+static void
+check_duplicated_redirections(const char *name, size_t len,
+               redirect_flags_t oldflags, redirect_flags_t newflags)
+{
+       static struct mixture {
+               redirect_flags_t common;
+               redirect_flags_t mode;
+               redirect_flags_t other_mode;
+               const char *message;
+       } mixtures[] = {
+               { RED_FILE, RED_READ, RED_WRITE,
+                       gettext_noop("`%.*s' used for input file and for output 
file") },
+               { RED_READ, RED_FILE, RED_PIPE,
+                       gettext_noop("`%.*s' used for input file and input 
pipe") },
+               { RED_READ, RED_FILE, RED_TWOWAY,
+                       gettext_noop("`%.*s' used for input file and two-way 
pipe") },
+               { RED_NONE, (RED_FILE|RED_READ), (RED_PIPE|RED_WRITE),
+                       gettext_noop("`%.*s' used for input file and output 
pipe") },
+               { (RED_FILE|RED_WRITE), (RED_FILE|RED_WRITE), RED_APPEND,
+                       gettext_noop("unnecessary mixing of `>' and `>>' for 
file `%.*s'") },
+               { RED_NONE, (RED_FILE|RED_WRITE), (RED_PIPE|RED_READ),
+                       gettext_noop("`%.*s' used for input pipe and output 
file") },
+               { RED_WRITE, RED_FILE, RED_PIPE,
+                       gettext_noop("`%.*s' used for output file and output 
pipe") },
+               { RED_WRITE, RED_FILE, RED_TWOWAY,
+                       gettext_noop("`%.*s' used for output file and two-way 
pipe") },
+               { RED_PIPE, RED_READ, RED_WRITE,
+                       gettext_noop("`%.*s' used for input pipe and output 
pipe") },
+               { RED_READ, RED_PIPE, RED_TWOWAY,
+                       gettext_noop("`%.*s' used for input pipe and two-way 
pipe") },
+               { RED_WRITE, RED_PIPE, RED_TWOWAY,
+                       gettext_noop("`%.*s' used for output pipe and two-way 
pipe") },
+       };
+       int i = 0, j = sizeof(mixtures) / sizeof(mixtures[0]);
+
+       oldflags &= ~(RED_NOBUF|RED_EOF|RED_PTY);
+       newflags &= ~(RED_NOBUF|RED_EOF|RED_PTY);
+
+       for (i = 0; i < j; i++) {
+               bool both_have_common = \
+                       (   (oldflags & mixtures[i].common) == 
mixtures[i].common
+                        && (newflags & mixtures[i].common) == 
mixtures[i].common);
+               bool old_has_mode = (oldflags & mixtures[i].mode) == 
mixtures[i].mode;
+               bool new_has_mode = (newflags & mixtures[i].mode) == 
mixtures[i].mode;
+               bool old_has_other_mode = (oldflags & mixtures[i].other_mode) 
== mixtures[i].other_mode;
+               bool new_has_other_mode = (newflags & mixtures[i].other_mode) 
== mixtures[i].other_mode;
+
+               if (   both_have_common
+                   && oldflags != newflags
+                   && (   (old_has_mode || new_has_mode)
+                       && (old_has_other_mode || new_has_other_mode)))
+               {
+                       lintwarn(_(mixtures[i].message), len, name);
+                       return;
+               }
+       }
+}
+
 /* redirect_string --- Redirection for printf and print commands, use string 
info */
 
 struct redirect *
@@ -735,8 +798,8 @@ redirect_string(const char *str, size_t explen, bool 
not_string,
                int redirtype, int *errflg, int extfd, bool failure_fatal)
 {
        struct redirect *rp;
-       int tflag = 0;
-       int outflag = 0;
+       redirect_flags_t tflag = RED_NONE;
+       redirect_flags_t outflag = RED_NONE;
        const char *direction = "to";
        const char *mode;
        int fd;
@@ -831,20 +894,16 @@ redirect_string(const char *str, size_t explen, bool 
not_string,
 
                /* now check for a match */
                if (strlen(rp->value) == explen
-                   && memcmp(rp->value, str, explen) == 0
-                   && ((rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY)) == tflag
-                       || (outflag != 0
-                           && (rp->flag & (RED_FILE|RED_WRITE)) == outflag))) {
-
-                       int rpflag = (rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY));
-                       int newflag = (tflag & ~(RED_NOBUF|RED_EOF|RED_PTY));
-
-                       if (do_lint && rpflag != newflag)
-                               lintwarn(
-               _("unnecessary mixing of `>' and `>>' for file `%.*s'"),
-                                       (int) explen, rp->value);
+                   && memcmp(rp->value, str, explen) == 0) {
+                       if (do_lint) {
+                               check_duplicated_redirections(rp->value, 
explen, rp->flag, tflag);
+                       }
 
-                       break;
+                       if (((rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY)) == tflag
+                           || (outflag != 0
+                               && (rp->flag & (RED_FILE|RED_WRITE)) == 
outflag))) {
+                               break;
+                       }
                }
        }
 
@@ -1341,6 +1400,9 @@ close_redir(struct redirect *rp, bool exitwarn, 
two_way_close_type how)
                        if ((rp->flag & RED_PIPE) != 0)
                                lintwarn(_("failure status (%d) on pipe close 
of `%s': %s"),
                                         status, rp->value, s);
+                       else if ((rp->flag & RED_TWOWAY) != 0)
+                               lintwarn(_("failure status (%d) on two-way pipe 
close of `%s': %s"),
+                                        status, rp->value, s);
                        else
                                lintwarn(_("failure status (%d) on file close 
of `%s': %s"),
                                         status, rp->value, s);
diff --git a/pc/ChangeLog b/pc/ChangeLog
index d58d295..428ba03 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,7 @@
+2020-09-21         Arnold D. Robbins     <arnold@skeeve.com>
+
+       * Makefile.tst: Rebuilt.
+
 2020-08-17         Arnold D. Robbins     <arnold@skeeve.com>
 
        * Makefile.tst: Rebuilt.
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index 9884119..a09b8d1 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -202,7 +202,7 @@ GAWK_EXT_TESTS = \
        genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind 
\
        icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
        incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
-       indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
+       indirectbuiltin indirectcall indirectcall2 intarray iolint isarrayunset 
\
        lint lintexp lintindex lintint lintlength lintplus lintold lintset 
lintwarn \
        manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
        nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
@@ -1229,6 +1229,13 @@ typedregex4:
        @echo $@
        @$(AWK) -v x=@$(SLASH)foo/ -f "$(srcdir)"/$@.awk y=@$(SLASH)bar/ 
/dev/null >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
        @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+iolint:
+       @echo $@
+       @echo hello > 'echo hello'
+       @$(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+       @-$(RM) -f cat 'echo hello' f1 f2 md5sum
 Gt-dummy:
 # file Maketests, generated from Makefile.am by the Gentests program
 addcomma:
diff --git a/test/ChangeLog b/test/ChangeLog
index e9199f8..eb3899c 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,9 @@
+2020-09-21         Arnold D. Robbins     <arnold@skeeve.com>
+
+       * Makefile.am (EXTRA_DIST): New test iolint. Sort the list of
+       files beginning with 'i'.
+       * iolint.awk, iolint.ok: New files.
+
 2020-09-04         Arnold D. Robbins     <arnold@skeeve.com>
 
        * id.ok: Updated after code changes.
diff --git a/test/Makefile.am b/test/Makefile.am
index dcef19c..ff2ba12 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -522,9 +522,6 @@ EXTRA_DIST = \
        icasers.awk \
        icasers.in \
        icasers.ok \
-       inpref.awk \
-       inpref.in \
-       inpref.ok \
        id.awk \
        id.ok \
        igncdym.awk \
@@ -542,53 +539,56 @@ EXTRA_DIST = \
        ignrcase.awk \
        ignrcase.in \
        ignrcase.ok \
-       incdupe.ok \
        incdupe2.ok \
        incdupe3.ok \
        incdupe4.ok \
        incdupe5.ok \
        incdupe6.ok \
        incdupe7.ok \
+       incdupe.ok \
        inchello.awk \
        inclib.awk \
+       include2.ok \
        include.awk \
        include.ok \
-       include2.ok \
        indirectbuiltin.awk \
        indirectbuiltin.ok \
+       indirectcall2.awk \
+       indirectcall2.ok \
        indirectcall.awk \
        indirectcall.in \
        indirectcall.ok \
-       indirectcall2.awk \
-       indirectcall2.ok \
        inftest.awk \
        inftest.ok \
-       inplace.in \
-       inplace.1.in \
-       inplace.2.in \
-       inplace1.ok \
        inplace1.1.ok \
        inplace1.2.ok \
-       inplace2.ok \
-       inplace2.1.ok \
+       inplace.1.in \
+       inplace1.ok \
        inplace2.1.bak.ok \
-       inplace2.2.ok \
+       inplace2.1.ok \
        inplace2.2.bak.ok \
+       inplace2.2.ok \
        inplace2bcomp.1.ok \
        inplace2bcomp.1.orig.ok \
        inplace2bcomp.2.ok \
        inplace2bcomp.2.orig.ok \
        inplace2bcomp.ok \
-       inplace3.ok \
-       inplace3.1.ok \
+       inplace.2.in \
+       inplace2.ok \
        inplace3.1.bak.ok \
-       inplace3.2.ok \
+       inplace3.1.ok \
        inplace3.2.bak.ok \
+       inplace3.2.ok \
        inplace3bcomp.1.ok \
        inplace3bcomp.1.orig.ok \
        inplace3bcomp.2.ok \
        inplace3bcomp.2.orig.ok \
        inplace3bcomp.ok \
+       inplace3.ok \
+       inplace.in \
+       inpref.awk \
+       inpref.in \
+       inpref.ok \
        inputred.awk \
        inputred.ok \
        intarray.awk \
@@ -601,6 +601,8 @@ EXTRA_DIST = \
        intprec.ok \
        iobug1.awk \
        iobug1.ok \
+       iolint.awk \
+       iolint.ok \
        isarrayunset.awk \
        isarrayunset.ok \
        jarebug.awk \
@@ -1420,7 +1422,7 @@ GAWK_EXT_TESTS = \
        genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind 
\
        icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
        incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
-       indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
+       indirectbuiltin indirectcall indirectcall2 intarray iolint isarrayunset 
\
        lint lintexp lintindex lintint lintlength lintplus lintold lintset 
lintwarn \
        manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
        nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
@@ -2448,6 +2450,13 @@ typedregex4:
        @$(AWK) -v x=@/foo/ -f "$(srcdir)"/$@.awk y=@/bar/ /dev/null >_$@ 2>&1 
|| echo EXIT CODE: $$? >>_$@
        @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
 
+iolint:
+       @echo $@
+       @echo hello > 'echo hello'
+       @$(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+       @-$(RM) -f cat 'echo hello' f1 f2 md5sum
+
 # Targets generated for other tests:
 include Maketests
 
diff --git a/test/Makefile.in b/test/Makefile.in
index 491daed..a8848e8 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -785,9 +785,6 @@ EXTRA_DIST = \
        icasers.awk \
        icasers.in \
        icasers.ok \
-       inpref.awk \
-       inpref.in \
-       inpref.ok \
        id.awk \
        id.ok \
        igncdym.awk \
@@ -805,53 +802,56 @@ EXTRA_DIST = \
        ignrcase.awk \
        ignrcase.in \
        ignrcase.ok \
-       incdupe.ok \
        incdupe2.ok \
        incdupe3.ok \
        incdupe4.ok \
        incdupe5.ok \
        incdupe6.ok \
        incdupe7.ok \
+       incdupe.ok \
        inchello.awk \
        inclib.awk \
+       include2.ok \
        include.awk \
        include.ok \
-       include2.ok \
        indirectbuiltin.awk \
        indirectbuiltin.ok \
+       indirectcall2.awk \
+       indirectcall2.ok \
        indirectcall.awk \
        indirectcall.in \
        indirectcall.ok \
-       indirectcall2.awk \
-       indirectcall2.ok \
        inftest.awk \
        inftest.ok \
-       inplace.in \
-       inplace.1.in \
-       inplace.2.in \
-       inplace1.ok \
        inplace1.1.ok \
        inplace1.2.ok \
-       inplace2.ok \
-       inplace2.1.ok \
+       inplace.1.in \
+       inplace1.ok \
        inplace2.1.bak.ok \
-       inplace2.2.ok \
+       inplace2.1.ok \
        inplace2.2.bak.ok \
+       inplace2.2.ok \
        inplace2bcomp.1.ok \
        inplace2bcomp.1.orig.ok \
        inplace2bcomp.2.ok \
        inplace2bcomp.2.orig.ok \
        inplace2bcomp.ok \
-       inplace3.ok \
-       inplace3.1.ok \
+       inplace.2.in \
+       inplace2.ok \
        inplace3.1.bak.ok \
-       inplace3.2.ok \
+       inplace3.1.ok \
        inplace3.2.bak.ok \
+       inplace3.2.ok \
        inplace3bcomp.1.ok \
        inplace3bcomp.1.orig.ok \
        inplace3bcomp.2.ok \
        inplace3bcomp.2.orig.ok \
        inplace3bcomp.ok \
+       inplace3.ok \
+       inplace.in \
+       inpref.awk \
+       inpref.in \
+       inpref.ok \
        inputred.awk \
        inputred.ok \
        intarray.awk \
@@ -864,6 +864,8 @@ EXTRA_DIST = \
        intprec.ok \
        iobug1.awk \
        iobug1.ok \
+       iolint.awk \
+       iolint.ok \
        isarrayunset.awk \
        isarrayunset.ok \
        jarebug.awk \
@@ -1683,7 +1685,7 @@ GAWK_EXT_TESTS = \
        genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind 
\
        icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase incdupe \
        incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 include include2 \
-       indirectbuiltin indirectcall indirectcall2 intarray isarrayunset \
+       indirectbuiltin indirectcall indirectcall2 intarray iolint isarrayunset 
\
        lint lintexp lintindex lintint lintlength lintplus lintold lintset 
lintwarn \
        manyfiles match1 match2 match3 mbstr1 mbstr2 mixed1 mktime muldimposix \
        nastyparm negtime next nondec nondec2 nonfatal1 nonfatal2 nonfatal3 \
@@ -2894,6 +2896,13 @@ typedregex4:
        @echo $@
        @$(AWK) -v x=@/foo/ -f "$(srcdir)"/$@.awk y=@/bar/ /dev/null >_$@ 2>&1 
|| echo EXIT CODE: $$? >>_$@
        @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+iolint:
+       @echo $@
+       @echo hello > 'echo hello'
+       @$(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+       @-$(RM) -f cat 'echo hello' f1 f2 md5sum
 Gt-dummy:
 # file Maketests, generated from Makefile.am by the Gentests program
 addcomma:
diff --git a/test/iolint.awk b/test/iolint.awk
new file mode 100644
index 0000000..e740815
--- /dev/null
+++ b/test/iolint.awk
@@ -0,0 +1,71 @@
+BEGIN {
+       LINT = 1
+
+       # `%.*s' used for input file and for output file
+       print "hi" > "f1"
+       fflush("f1")
+       getline x < "f1"
+       print close("f1")
+       print close("f1")
+       fflush()
+
+       # `%.*s' used for input file and input pipe
+       # `%.*s' used for input file and two-way pipe
+       # `%.*s' used for input pipe and two-way pipe
+       getline data3 < "echo hello"
+       "echo hello" |& getline data2
+       "echo hello" | getline data
+
+       print data, data2, data3
+
+       print close("echo hello")
+       print close("echo hello")
+       print close("echo hello")
+       fflush()
+
+       # `%.*s' used for input file and output pipe
+       getline x < "cat"
+       print "foo" | "cat"
+       print close("cat")
+       print close("cat")
+       fflush()
+
+       # unnecessary mixing of `>' and `>>' for file `%.*s'
+       print "foo" >  "f2"
+       print "bar" >> "f2"
+       print close("f2")
+       print close("f2")       # -1 expected here
+       fflush()
+
+       # `%.*s' used for output file and output pipe"
+       print "junk" > "md5sum"
+       print "hello" | "md5sum"
+       print close("md5sum")
+       print close("md5sum")
+       fflush()
+
+       # `%.*s' used for input pipe and output file
+       "echo hello" | getline junk
+       print "hello" > "echo hello"
+       print close("echo hello")
+       print close("echo hello")
+       fflush()
+
+       # `%.*s' used for output file and output pipe
+       # `%.*s' used for output file and two-way pipe
+       # `%.*s' used for output pipe and two-way pipe
+       print "hello" > "cat"
+       print "hello" | "cat"
+       print "hello" |& "cat"
+       print close("cat")
+       print close("cat")
+       print close("cat")
+       fflush()
+
+       # `%.*s' used for input pipe and output pipe
+       "echo hello" | getline junk
+       print "hello" | "echo hello"
+       print close("echo hello")
+       print close("echo hello")
+       fflush()
+}
diff --git a/test/iolint.ok b/test/iolint.ok
new file mode 100644
index 0000000..1e325aa
--- /dev/null
+++ b/test/iolint.ok
@@ -0,0 +1,37 @@
+gawk: ./iolint.awk:7: warning: `f1' used for input file and for output file
+0
+0
+gawk: ./iolint.awk:16: warning: `echo hello' used for input file and two-way 
pipe
+gawk: ./iolint.awk:17: warning: `echo hello' used for input pipe and two-way 
pipe
+gawk: ./iolint.awk:17: warning: `echo hello' used for input file and input pipe
+hello hello hello
+0
+0
+0
+foo
+0
+gawk: ./iolint.awk:30: warning: close: `cat' is not an open file, pipe or 
co-process
+-1
+gawk: ./iolint.awk:35: warning: unnecessary mixing of `>' and `>>' for file 
`f2'
+0
+gawk: ./iolint.awk:37: warning: close: `f2' is not an open file, pipe or 
co-process
+-1
+gawk: ./iolint.awk:42: warning: `md5sum' used for output file and output pipe
+b1946ac92492d2347c6235b4d2611184  -
+0
+0
+gawk: ./iolint.awk:49: warning: `echo hello' used for input pipe and output 
file
+0
+0
+gawk: ./iolint.awk:58: warning: `cat' used for output file and output pipe
+gawk: ./iolint.awk:59: warning: `cat' used for output pipe and two-way pipe
+gawk: ./iolint.awk:59: warning: `cat' used for output file and two-way pipe
+hello
+gawk: ./iolint.awk:60: warning: failure status (141) on two-way pipe close of 
`cat': Success
+141
+0
+0
+gawk: ./iolint.awk:67: warning: `echo hello' used for input pipe and output 
pipe
+hello
+0
+0

-----------------------------------------------------------------------


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]