about summary refs log tree commit diff
path: root/Src/parse.c
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2015-01-08 21:39:26 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2015-01-09 21:33:39 +0000
commitcfd91eac0732da8ece012ca4ab051d928a85c9dd (patch)
tree68ef32e118a060de0c7685c848e0267e64cf5137 /Src/parse.c
parent6291d38848680b84252799d9e33110bca842efe8 (diff)
downloadzsh-cfd91eac0732da8ece012ca4ab051d928a85c9dd.tar.gz
zsh-cfd91eac0732da8ece012ca4ab051d928a85c9dd.tar.xz
zsh-cfd91eac0732da8ece012ca4ab051d928a85c9dd.zip
Rearrange context saving.
Variables are now associated with the module that declares them, being
initialised and saved/restored there.  However, as many variables are
used for communication between modules, many of them are set in multiple
places, so the assignment is ambiguous.
Diffstat (limited to 'Src/parse.c')
-rw-r--r--Src/parse.c83
1 files changed, 80 insertions, 3 deletions
diff --git a/Src/parse.c b/Src/parse.c
index fa37ca3d9..0b54a904d 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -31,7 +31,7 @@
 #include "parse.pro"
 
 /* != 0 if we are about to read a command word */
- 
+
 /**/
 mod_export int incmdpos;
 
@@ -242,6 +242,67 @@ int ecsoffs, ecssub, ecnfunc;
 #define EC_DOUBLE_THRESHOLD  32768
 #define EC_INCREMENT         1024
 
+/* save parse context */
+
+/**/
+void
+parse_context_save(struct parse_stack *ps, int toplevel)
+{
+    (void)toplevel;
+
+    ps->incmdpos = incmdpos;
+    ps->aliasspaceflag = aliasspaceflag;
+    ps->incond = incond;
+    ps->inredir = inredir;
+    ps->incasepat = incasepat;
+    ps->isnewlin = isnewlin;
+    ps->infor = infor;
+
+    ps->hdocs = hdocs;
+    ps->eclen = eclen;
+    ps->ecused = ecused;
+    ps->ecnpats = ecnpats;
+    ps->ecbuf = ecbuf;
+    ps->ecstrs = ecstrs;
+    ps->ecsoffs = ecsoffs;
+    ps->ecssub = ecssub;
+    ps->ecnfunc = ecnfunc;
+    ecbuf = NULL;
+    hdocs = NULL;
+}
+
+/* restore parse context */
+
+/**/
+void
+parse_context_restore(const struct parse_stack *ps, int toplevel)
+{
+    (void)toplevel;
+
+    if (ecbuf)
+	zfree(ecbuf, eclen);
+
+    incmdpos = ps->incmdpos;
+    aliasspaceflag = ps->aliasspaceflag;
+    incond = ps->incond;
+    inredir = ps->inredir;
+    incasepat = ps->incasepat;
+    incasepat = ps->incasepat;
+    isnewlin = ps->isnewlin;
+    infor = ps->infor;
+
+    hdocs = ps->hdocs;
+    eclen = ps->eclen;
+    ecused = ps->ecused;
+    ecnpats = ps->ecnpats;
+    ecbuf = ps->ecbuf;
+    ecstrs = ps->ecstrs;
+    ecsoffs = ps->ecsoffs;
+    ecssub = ps->ecssub;
+    ecnfunc = ps->ecnfunc;
+
+    errflag &= ~ERRFLAG_ERROR;
+}
 
 /* Adjust pointers in here-doc structs. */
 
@@ -359,6 +420,21 @@ ecstrcode(char *s)
     } while (0)
 
 
+/**/
+mod_export void
+init_parse_status(void)
+{
+    /*
+     * These variables are currently declared by the parser, so we
+     * initialise them here.  Possibly they are more naturally declared
+     * by the lexical anaylser; however, as they are used for signalling
+     * between the two it's a bit ambiguous.  We clear them when
+     * using the lexical analyser for strings as well as here.
+     */
+    incasepat = incond = inredir = infor = 0;
+    incmdpos = 1;
+}
+
 /* Initialise wordcode buffer. */
 
 /**/
@@ -373,6 +449,8 @@ init_parse(void)
     ecsoffs = ecnpats = 0;
     ecssub = 0;
     ecnfunc = 0;
+
+    init_parse_status();
 }
 
 /* Build eprog. */
@@ -539,9 +617,8 @@ parse_list(void)
     int c = 0;
 
     tok = ENDINPUT;
-    incmdpos = 1;
-    zshlex();
     init_parse();
+    zshlex();
     par_list(&c);
     if (tok != ENDINPUT) {
         clear_hdocs();