Source-Changes-HG archive

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

[src/trunk]: src/bin/sh Implement PS1, PS2 and PS4 expansions (variable expan...



details:   https://anonhg.NetBSD.org/src/rev/6ce571353735
branches:  trunk
changeset: 825129:6ce571353735
user:      kre <kre%NetBSD.org@localhost>
date:      Fri Jun 30 23:02:56 2017 +0000

description:
Implement PS1, PS2 and PS4 expansions (variable expansions, arithmetic
expansions, and if enabled by the promptcmds option, command substitutions.)

diffstat:

 bin/sh/expand.c    |    8 +-
 bin/sh/input.c     |   41 ++++++++++++-
 bin/sh/input.h     |    6 +-
 bin/sh/option.list |    5 +-
 bin/sh/parser.c    |  165 +++++++++++++++++++++++++++++++++++++++++-----------
 bin/sh/parser.h    |   89 +++++++++++++++++++++++++---
 6 files changed, 258 insertions(+), 56 deletions(-)

diffs (truncated from 543 to 300 lines):

diff -r a420b6a16ebb -r 6ce571353735 bin/sh/expand.c
--- a/bin/sh/expand.c   Fri Jun 30 23:01:21 2017 +0000
+++ b/bin/sh/expand.c   Fri Jun 30 23:02:56 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: expand.c,v 1.118 2017/06/19 02:46:50 kre Exp $ */
+/*     $NetBSD: expand.c,v 1.119 2017/06/30 23:02:56 kre Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)expand.c   8.5 (Berkeley) 5/15/95";
 #else
-__RCSID("$NetBSD: expand.c,v 1.118 2017/06/19 02:46:50 kre Exp $");
+__RCSID("$NetBSD: expand.c,v 1.119 2017/06/30 23:02:56 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -177,7 +177,7 @@
        line_number = arg->narg.lineno;
        argstr(arg->narg.text, flag);
        if (arglist == NULL) {
-               NULLTERM_4_TRACE(expdest);
+               STACKSTRNUL(expdest);
                CTRACE(DBG_EXPAND, ("expandarg: no arglist, done (%d) \"%s\"\n",
                    expdest - stackblock(), stackblock()));
                return;                 /* here document expanded */
@@ -597,8 +597,10 @@
                if (--in.nleft < 0) {
                        if (in.fd < 0)
                                break;
+                       INTON;
                        while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR)
                                continue;
+                       INTOFF;
                        VTRACE(DBG_EXPAND, ("expbackq: read returns %d\n", i));
                        if (i <= 0)
                                break;
diff -r a420b6a16ebb -r 6ce571353735 bin/sh/input.c
--- a/bin/sh/input.c    Fri Jun 30 23:01:21 2017 +0000
+++ b/bin/sh/input.c    Fri Jun 30 23:02:56 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: input.c,v 1.58 2017/06/07 05:08:32 kre Exp $   */
+/*     $NetBSD: input.c,v 1.59 2017/06/30 23:02:56 kre Exp $   */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)input.c    8.3 (Berkeley) 6/9/95";
 #else
-__RCSID("$NetBSD: input.c,v 1.58 2017/06/07 05:08:32 kre Exp $");
+__RCSID("$NetBSD: input.c,v 1.59 2017/06/30 23:02:56 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -471,6 +471,7 @@
                parsefile->buf = ckmalloc(BUFSIZ);
        parselleft = parsenleft = 0;
        plinno = 1;
+       CTRACE(DBG_INPUT, ("setinputfd(%d, %d); plinno=1\n", fd, push));
 }
 
 
@@ -489,7 +490,7 @@
        parselleft = parsenleft = strlen(string);
        parsefile->buf = NULL;
        plinno = line1;
-       TRACE(("setinputstring(\"%.20s%s\" (%d), %d, %d)\n", string,
+       CTRACE(DBG_INPUT, ("setinputstring(\"%.20s%s\" (%d), %d, %d)\n", string,
            (parsenleft > 20 ? "..." : ""), parsenleft, push, line1));
        INTON;
 }
@@ -506,6 +507,10 @@
 {
        struct parsefile *pf;
 
+       VTRACE(DBG_INPUT, ("pushfile(): fd=%d nl=%d ll=%d \"%.*s\" plinno=%d\n",
+           parsefile->fd, parsenleft, parselleft,
+           parsenleft, parsenextc, plinno));
+
        parsefile->nleft = parsenleft;
        parsefile->lleft = parselleft;
        parsefile->nextc = parsenextc;
@@ -536,10 +541,40 @@
        parsenleft = parsefile->nleft;
        parselleft = parsefile->lleft;
        parsenextc = parsefile->nextc;
+       VTRACE(DBG_INPUT,
+           ("popfile(): fd=%d nl=%d ll=%d \"%.*s\" plinno:%d->%d\n",
+           parsefile->fd, parsenleft, parselleft,
+           parsenleft, parsenextc, plinno, parsefile->linno));
        plinno = parsefile->linno;
        INTON;
 }
 
+/*
+ * Return current file (to go back to it later using popfilesupto()).
+ */
+
+struct parsefile *
+getcurrentfile(void)
+{
+       return parsefile;
+}
+
+
+/*
+ * Pop files until the given file is on top again. Useful for regular
+ * builtins that read shell commands from files or strings.
+ * If the given file is not an active file, an error is raised.
+ */
+
+void
+popfilesupto(struct parsefile *file)
+{
+       while (parsefile != file && parsefile != &basepf)
+               popfile();
+       if (parsefile != file)
+               error("popfilesupto() misused");
+}
+
 
 /*
  * Return to top level.
diff -r a420b6a16ebb -r 6ce571353735 bin/sh/input.h
--- a/bin/sh/input.h    Fri Jun 30 23:01:21 2017 +0000
+++ b/bin/sh/input.h    Fri Jun 30 23:02:56 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: input.h,v 1.19 2017/06/07 04:44:17 kre Exp $   */
+/*     $NetBSD: input.h,v 1.20 2017/06/30 23:02:56 kre Exp $   */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -45,8 +45,10 @@
 extern int parsenleft;         /* number of characters left in input buffer */
 extern const char *parsenextc; /* next character in input buffer */
 extern int init_editline;      /* 0 == not setup, 1 == OK, -1 == failed */
+extern int whichprompt;                /* 1 ==> PS1, 2 ==> PS2 */
 
 struct alias;
+struct parsefile;
 
 char *pfgets(char *, int);
 int pgetc(void);
@@ -58,6 +60,8 @@
 void setinputfd(int, int);
 void setinputstring(char *, int, int);
 void popfile(void);
+struct parsefile *getcurrentfile(void);
+void popfilesupto(struct parsefile *);
 void popallfiles(void);
 void closescript(int);
 
diff -r a420b6a16ebb -r 6ce571353735 bin/sh/option.list
--- a/bin/sh/option.list        Fri Jun 30 23:01:21 2017 +0000
+++ b/bin/sh/option.list        Fri Jun 30 23:02:56 2017 +0000
@@ -1,10 +1,10 @@
-/* $NetBSD: option.list,v 1.4 2017/06/17 07:50:35 kre Exp $ */
+/* $NetBSD: option.list,v 1.5 2017/06/30 23:02:56 kre Exp $ */
 
 /*
  * define the shell's settable options
  *
  *     new options can be defined by adding them here,
- *     but they do nothing untilcode to implement them
+ *     but they do nothing until code to implement them
  *     is added (using the "var name" field)
  */
 
@@ -64,6 +64,7 @@
 posix  posix                           # be closer to POSIX compat
 qflag  quietprofile    q               # disable -v/-x in startup files
 fnline1        local_lineno    L on            # number lines in funcs starting at 1
+promptcmds promptcmds                  # allow $( ) in PS1 (et al).
 
 // editline/history related options ("vi" is standard, 'V' and others are not)
 // only one of vi/emacs can be set, hence the "set" definition, value
diff -r a420b6a16ebb -r 6ce571353735 bin/sh/parser.c
--- a/bin/sh/parser.c   Fri Jun 30 23:01:21 2017 +0000
+++ b/bin/sh/parser.c   Fri Jun 30 23:02:56 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.139 2017/06/24 11:23:35 kre Exp $ */
+/*     $NetBSD: parser.c,v 1.140 2017/06/30 23:02:56 kre Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c   8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.139 2017/06/24 11:23:35 kre Exp $");
+__RCSID("$NetBSD: parser.c,v 1.140 2017/06/30 23:02:56 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -74,34 +74,34 @@
 #define OPENBRACE '{'
 #define CLOSEBRACE '}'
 
-
-struct heredoc {
-       struct heredoc *next;   /* next here document in list */
+struct HereDoc {
+       struct HereDoc *next;   /* next here document in list */
        union node *here;               /* redirection node */
        char *eofmark;          /* string indicating end of input */
        int striptabs;          /* if set, strip leading tabs */
        int startline;          /* line number where << seen */
 };
 
-
+MKINIT struct parse_state parse_state;
+union parse_state_p psp = { .c_current_parser = &parse_state };
 
-static int noalias = 0;                /* when set, don't handle aliases */
-struct heredoc *heredoclist;   /* list of here documents to read */
-int parsebackquote;            /* nonzero if we are inside backquotes */
-int doprompt;                  /* if set, prompt the user */
-int needprompt;                        /* true if interactive and at start of line */
-int lasttoken;                 /* last token read */
-MKINIT int tokpushback;                /* last token pushed back */
-char *wordtext;                        /* text of last word returned by readtoken */
-MKINIT int checkkwd;           /* 1 == check for kwds, 2 == also eat newlines */
-struct nodelist *backquotelist;
-union node *redirnode;
-struct heredoc *heredoc;
-int quoteflag;                 /* set if (part of) last token was quoted */
-int startlinno;                        /* line # where last token started */
-int funclinno;                 /* line # where the current function started */
-int elided_nl;                 /* count of \ \n (deleted \n's) we have seen */
-
+static const struct parse_state init_parse_state = {   /* all 0's ... */
+       .ps_noalias = 0,
+       .ps_heredoclist = NULL,
+       .ps_parsebackquote = 0,
+       .ps_doprompt = 0,
+       .ps_needprompt = 0,
+       .ps_lasttoken = 0,
+       .ps_tokpushback = 0,
+       .ps_wordtext = NULL,
+       .ps_checkkwd = 0,
+       .ps_redirnode = NULL,
+       .ps_heredoc = NULL,
+       .ps_quoteflag = 0,
+       .ps_startlinno = 0,
+       .ps_funclinno = 0,
+       .ps_elided_nl = 0,
+};
 
 STATIC union node *list(int, int);
 STATIC union node *andor(void);
@@ -122,7 +122,6 @@
 STATIC void setprompt(int);
 STATIC int pgetc_linecont(void);
 
-
 static const char EOFhere[] = "EOF reading here (<<) document";
 
 #ifdef DEBUG
@@ -758,8 +757,8 @@
        if (readtoken() != TWORD)
                synexpect(-1, 0);
        if (n->type == NHERE) {
-               struct heredoc *here = heredoc;
-               struct heredoc *p;
+               struct HereDoc *here = heredoc;
+               struct HereDoc *p;
 
                if (quoteflag == 0)
                        n->type = NXHERE;
@@ -948,7 +947,7 @@
 STATIC void
 readheredocs(void)
 {
-       struct heredoc *here;
+       struct HereDoc *here;
        union node *n;
        int line, l;
 
@@ -1012,7 +1011,7 @@
 #endif
        struct alias *ap;
 
-       top:
+ top:
        t = xxreadtoken();
 
        if (checkkwd) {
@@ -1045,6 +1044,9 @@
                        }
                        if (!noalias &&
                            (ap = lookupalias(wordtext, 1)) != NULL) {
+                               VTRACE(DBG_PARSE,
+                                   ("alias '%s' recognized -> <:%s:>\n",
+                                   wordtext, ap->val));
                                pushstring(ap->val, strlen(ap->val), ap);
                                checkkwd = savecheckkwd;
                                goto top;
@@ -1547,7 +1549,7 @@



Home | Main Index | Thread Index | Old Index