From cfd91eac0732da8ece012ca4ab051d928a85c9dd Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 8 Jan 2015 21:39:26 +0000 Subject: 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. --- Src/Zle/compcore.c | 4 +- Src/Zle/compctl.c | 8 +- Src/Zle/textobjects.c | 4 +- Src/Zle/zle_tricky.c | 24 ++-- Src/builtin.c | 8 +- Src/context.c | 116 ++++++++++++++++++ Src/exec.c | 8 +- Src/hist.c | 88 +++++++++++++- Src/init.c | 4 +- Src/lex.c | 321 ++++++++++---------------------------------------- Src/parse.c | 83 ++++++++++++- Src/signals.c | 4 +- Src/zsh.h | 65 ++++++++++ Src/zsh.mdd | 3 +- 14 files changed, 441 insertions(+), 299 deletions(-) create mode 100644 Src/context.c (limited to 'Src') diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index f5056058a..000f9da2a 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1524,7 +1524,7 @@ set_comp_sep(void) ol = zlemetaline; addedx = 1; noerrs = 1; - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ZLE; /* * tl is the length of the temporary string including @@ -1673,7 +1673,7 @@ set_comp_sep(void) inpop(); errflag &= ~ERRFLAG_ERROR; noerrs = ne; - lexrestore(); + zcontext_restore(); wb = owb; we = owe; zlemetaline = ol; diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 2a80e6c84..43dd4e2a9 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -2795,7 +2795,7 @@ sep_comp_string(char *ss, char *s, int noffs) * get the words we have to expand. */ addedx = 1; noerrs = 1; - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ZLE; tmp = (char *) zhalloc(tl = sl + 3 + strlen(s)); strcpy(tmp, ss); @@ -2849,7 +2849,7 @@ sep_comp_string(char *ss, char *s, int noffs) inpop(); errflag &= ~ERRFLAG_ERROR; noerrs = ne; - lexrestore(); + zcontext_restore(); wb = owb; we = owe; zlemetacs = ocs; @@ -3707,7 +3707,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* Put the string in the lexer buffer and call the lexer to * * get the words we have to expand. */ - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ZLE; tmpbuf = (char *)zhalloc(strlen(cc->str) + 5); sprintf(tmpbuf, "foo %s", cc->str); /* KLUDGE! */ @@ -3726,7 +3726,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) strinend(); inpop(); errflag &= ~ERRFLAG_ERROR; - lexrestore(); + zcontext_restore(); /* Fine, now do full expansion. */ prefork(foo, 0); if (!errflag) { diff --git a/Src/Zle/textobjects.c b/Src/Zle/textobjects.c index 37d2c0ad9..9b3277a97 100644 --- a/Src/Zle/textobjects.c +++ b/Src/Zle/textobjects.c @@ -241,7 +241,7 @@ selectargument(UNUSED(char **args)) addedx = 0; noerrs = 1; - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ACTIVE; linein = zlegetline(&ll, &cs); zlemetall = ll; @@ -277,7 +277,7 @@ selectargument(UNUSED(char **args)) inpop(); errflag &= ~ERRFLAG_ERROR; noerrs = ne; - lexrestore(); + zcontext_restore(); zlemetacs = ocs; wb = owb; we = owe; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 950c22f38..f18ad170e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -698,7 +698,7 @@ docomplete(int lst) freeheap(); /* Save the lexer state, in case the completion code uses the lexer * * somewhere (e.g. when processing a compctl -s flag). */ - lexsave(); + zcontext_save(); if (inwhat == IN_ENV) lincmd = 0; if (s) { @@ -868,7 +868,7 @@ docomplete(int lst) } else ret = 1; /* Reset the lexer state, pop the heap. */ - lexrestore(); + zcontext_restore(); popheap(); dat[0] = lst; @@ -1164,7 +1164,7 @@ get_comp_string(void) varname = NULL; insubscr = 0; clwpos = -1; - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ZLE; inpush(dupstrspace(linptr), 0, NULL); strinbeg(0); @@ -1422,7 +1422,7 @@ get_comp_string(void) zlemetall -= parend; zlemetaline[zlemetall + addedx] = '\0'; } - lexrestore(); + zcontext_restore(); tt = NULL; goto start; } @@ -1496,12 +1496,12 @@ get_comp_string(void) if (tmp) { tmp = NULL; linptr = zlemetaline; - lexrestore(); + zcontext_restore(); addedx = 0; goto start; } noaliases = ona; - lexrestore(); + zcontext_restore(); return NULL; } @@ -2151,7 +2151,7 @@ get_comp_string(void) offs = boffs; } } - lexrestore(); + zcontext_restore(); return (char *)s; } @@ -2791,7 +2791,7 @@ doexpandhist(void) expanding = 1; excs = zlemetacs; zlemetall = zlemetacs = 0; - lexsave(); + zcontext_save(); /* We push ol as it will remain unchanged */ inpush(ol, 0, NULL); strinbeg(1); @@ -2803,7 +2803,7 @@ doexpandhist(void) } while (tok != ENDINPUT && tok != LEXERR); while (!lexstop) hgetc(); - /* We have to save errflags because it's reset in lexrestore. Since * + /* We have to save errflags because it's reset in zcontext_restore. Since * * noerrs was set to 1 errflag is true if there was a habort() which * * means that the expanded string is unusable. */ err = errflag; @@ -2811,7 +2811,7 @@ doexpandhist(void) noaliases = ona; strinend(); inpop(); - lexrestore(); + zcontext_restore(); expanding = 0; if (!err) { @@ -2910,7 +2910,7 @@ getcurcmd(void) int curlincmd; char *s = NULL; - lexsave(); + zcontext_save(); lexflags = LEXFLAGS_ZLE; metafy_line(); inpush(dupstrspace(zlemetaline), 0, NULL); @@ -2934,7 +2934,7 @@ getcurcmd(void) inpop(); errflag &= ~ERRFLAG_ERROR; unmetafy_line(); - lexrestore(); + zcontext_restore(); return s; } diff --git a/Src/builtin.c b/Src/builtin.c index d2108264f..8abe728db 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -6102,7 +6102,7 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) } } - lexsave(); + zcontext_save(); testargs = argv; tok = NULLTOK; condlex = testlex; @@ -6112,16 +6112,16 @@ bin_test(char *name, char **argv, UNUSED(Options ops), int func) if (errflag) { errflag &= ~ERRFLAG_ERROR; - lexrestore(); + zcontext_restore(); return 1; } if (!prog || tok == LEXERR) { zwarnnam(name, tokstr ? "parse error" : "argument expected"); - lexrestore(); + zcontext_restore(); return 1; } - lexrestore(); + zcontext_restore(); if (*curtestarg) { zwarnnam(name, "too many arguments"); diff --git a/Src/context.c b/Src/context.c new file mode 100644 index 000000000..bd8d191bf --- /dev/null +++ b/Src/context.c @@ -0,0 +1,116 @@ +/* + * context.c - context save and restore + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1992-1997 Paul Falstad + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Paul Falstad or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Paul Falstad and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Paul Falstad and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Paul Falstad and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ +/* + * This short file provides a home for the stack of saved contexts. + * The actions for saving and restoring are encapsulated within + * individual modules. + */ + +#include "zsh.mdh" +#include "context.pro" + +struct context_stack { + struct context_stack *next; + + struct hist_stack hist_stack; + struct lex_stack lex_stack; + struct parse_stack parse_stack; +}; + +static struct context_stack *cstack; + +/* save some or all of current context */ + +/**/ +mod_export void +zcontext_save_partial(int parts) +{ + struct context_stack *cs; + + cs = (struct context_stack *)malloc(sizeof(struct context_stack)); + + if (parts & ZCONTEXT_HIST) { + hist_context_save(&cs->hist_stack, !cstack); + } + if (parts & ZCONTEXT_LEX) { + lex_context_save(&cs->lex_stack, !cstack); + } + if (parts & ZCONTEXT_PARSE) { + parse_context_save(&cs->parse_stack, !cstack); + } + + cs->next = cstack; + cstack = cs; +} + +/* save context in full */ + +/**/ +mod_export void +zcontext_save(void) +{ + zcontext_save_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE); +} + +/* restore context or part thereof */ + +/**/ +mod_export void +zcontext_restore_partial(int parts) +{ + struct context_stack *cs = cstack; + + DPUTS(!cstack, "BUG: zcontext_restore() without zcontext_save()"); + + queue_signals(); + cstack = cstack->next; + + if (parts & ZCONTEXT_HIST) { + hist_context_restore(&cs->hist_stack, !cstack); + } + if (parts & ZCONTEXT_LEX) { + lex_context_restore(&cs->lex_stack, !cstack); + } + if (parts & ZCONTEXT_PARSE) { + parse_context_restore(&cs->parse_stack, !cstack); + } + + free(cs); + + unqueue_signals(); +} + +/* restore full context */ + +/**/ +mod_export void +zcontext_restore(void) +{ + zcontext_restore_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE); +} diff --git a/Src/exec.c b/Src/exec.c index ab9291024..7b6495113 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -217,7 +217,7 @@ parse_string(char *s, int reset_lineno) Eprog p; zlong oldlineno; - lexsave(); + zcontext_save(); inpush(s, INP_LINENO, NULL); strinbeg(0); oldlineno = lineno; @@ -229,7 +229,7 @@ parse_string(char *s, int reset_lineno) lastval = 1; strinend(); inpop(); - lexrestore(); + zcontext_restore(); return p; } @@ -3349,9 +3349,9 @@ execcmd(Estate state, int input, int output, int how, int last1) * The copy uses the wordcode parsing area, so save and * restore state. */ - lexsave(); + zcontext_save(); redir_prog = eccopyredirs(&s); - lexrestore(); + zcontext_restore(); } else redir_prog = NULL; diff --git a/Src/hist.c b/Src/hist.c index e65d78bfd..447f00e84 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -222,6 +222,85 @@ static int histsave_stack_pos = 0; static zlong histfile_linect; +/* save history context */ + +/**/ +void +hist_context_save(struct hist_stack *hs, int toplevel) +{ + if (toplevel) { + /* top level, make this version visible to ZLE */ + zle_chline = chline; + /* ensure line stored is NULL-terminated */ + if (hptr) + *hptr = '\0'; + } + hs->histactive = histactive; + hs->histdone = histdone; + hs->stophist = stophist; + hs->hline = chline; + hs->hptr = hptr; + hs->chwords = chwords; + hs->chwordlen = chwordlen; + hs->chwordpos = chwordpos; + hs->hwgetword = hwgetword; + hs->hgetc = hgetc; + hs->hungetc = hungetc; + hs->hwaddc = hwaddc; + hs->hwbegin = hwbegin; + hs->hwend = hwend; + hs->addtoline = addtoline; + hs->hlinesz = hlinesz; + /* + * We save and restore the command stack with history + * as it's visible to the user interactively, so if + * we're preserving history state we'll continue to + * show the current set of commands from input. + */ + hs->cstack = cmdstack; + hs->csp = cmdsp; + + stophist = 0; + chline = NULL; + hptr = NULL; + histactive = 0; + cmdstack = (unsigned char *)zalloc(CMDSTACKSZ); + cmdsp = 0; +} + +/**/ +void +hist_context_restore(const struct hist_stack *hs, int toplevel) +{ + if (toplevel) { + /* Back to top level: don't need special ZLE value */ + DPUTS(hs->hline != zle_chline, "BUG: Ouch, wrong chline for ZLE"); + zle_chline = NULL; + } + histactive = hs->histactive; + histdone = hs->histdone; + stophist = hs->stophist; + chline = hs->hline; + hptr = hs->hptr; + chwords = hs->chwords; + chwordlen = hs->chwordlen; + chwordpos = hs->chwordpos; + hwgetword = hs->hwgetword; + hgetc = hs->hgetc; + hungetc = hs->hungetc; + hwaddc = hs->hwaddc; + hwbegin = hs->hwbegin; + hwend = hs->hwend; + addtoline = hs->addtoline; + hlinesz = hs->hlinesz; + if (cmdstack) + zfree(cmdstack, CMDSTACKSZ); + cmdstack = hs->cstack; + cmdsp = hs->csp; +} + +/* restore history context */ + /* add a character to the current history word */ static void @@ -815,6 +894,11 @@ strinbeg(int dohist) strin++; hbegin(dohist); lexinit(); + /* + * Also initialise some variables owned by the parser but + * used for communication between the parser and lexer. + */ + init_parse_status(); } /* done reading a string */ @@ -2992,7 +3076,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags) opts[RCQUOTES] = 0; addedx = 0; noerrs = 1; - lexsave(); + zcontext_save(); lexflags = flags | LEXFLAGS_ACTIVE; /* * Are we handling comments? @@ -3189,7 +3273,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags) errflag &= ~ERRFLAG_ERROR; nocomments = onc; noerrs = ne; - lexrestore(); + zcontext_restore(); zlemetacs = ocs; zlemetall = oll; wb = owb; diff --git a/Src/init.c b/Src/init.c index 080fc8561..e7d86feac 100644 --- a/Src/init.c +++ b/Src/init.c @@ -107,7 +107,7 @@ loop(int toplevel, int justonce) pushheap(); if (!toplevel) - lexsave(); + zcontext_save(); for (;;) { freeheap(); if (stophist == 3) /* re-entry via preprompt() */ @@ -227,7 +227,7 @@ loop(int toplevel, int justonce) } err = errflag; if (!toplevel) - lexrestore(); + zcontext_restore(); popheap(); if (err) diff --git a/Src/lex.c b/Src/lex.c index d440f3d70..69441b28d 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -203,263 +203,64 @@ static int dbparens; static int len = 0, bsiz = 256; static char *bptr; -struct lexstack { - struct lexstack *next; - - int incmdpos; - int incond; - int incasepat; - int dbparens; - int isfirstln; - int isfirstch; - int histactive; - int histdone; - int lexflags; - int stophist; - int hlinesz; - char *hline; - char *hptr; - enum lextok tok; - int isnewlin; - char *tokstr; - char *zshlextext; - char *bptr; - int bsiz; - int len; - int lex_add_raw; - char *tokstr_raw; - char *bptr_raw; - int bsiz_raw; - int len_raw; - short *chwords; - int chwordlen; - int chwordpos; - int hwgetword; - int lexstop; - struct heredocs *hdocs; - int (*hgetc) _((void)); - void (*hungetc) _((int)); - void (*hwaddc) _((int)); - void (*hwbegin) _((int)); - void (*hwend) _((void)); - void (*addtoline) _((int)); - - int eclen, ecused, ecnpats; - Wordcode ecbuf; - Eccstr ecstrs; - int ecsoffs, ecssub, ecnfunc; - - unsigned char *cstack; - int csp; - zlong toklineno; -}; - -static struct lexstack *lstack = NULL; - -/* save the context or parts thereof */ - -/* is this a hack or what? */ +/* save lexical context */ /**/ -mod_export void -lexsave_partial(int parts) -{ - struct lexstack *ls; - - ls = (struct lexstack *)malloc(sizeof(struct lexstack)); - - if (parts & ZCONTEXT_LEX) { - ls->incmdpos = incmdpos; - ls->incond = incond; - ls->incasepat = incasepat; - ls->dbparens = dbparens; - ls->isfirstln = isfirstln; - ls->isfirstch = isfirstch; - ls->lexflags = lexflags; - - ls->tok = tok; - ls->isnewlin = isnewlin; - ls->tokstr = tokstr; - ls->zshlextext = zshlextext; - ls->bptr = bptr; - ls->bsiz = bsiz; - ls->len = len; - ls->lex_add_raw = lex_add_raw; - ls->tokstr_raw = tokstr_raw; - ls->bptr_raw = bptr_raw; - ls->bsiz_raw = bsiz_raw; - ls->len_raw = len_raw; - ls->lexstop = lexstop; - ls->toklineno = toklineno; - - tokstr = zshlextext = bptr = NULL; - bsiz = 256; - tokstr_raw = bptr_raw = NULL; - bsiz_raw = len_raw = lex_add_raw = 0; - - inredir = 0; - } - if (parts & ZCONTEXT_HIST) { - if (!lstack) { - /* top level, make this version visible to ZLE */ - zle_chline = chline; - /* ensure line stored is NULL-terminated */ - if (hptr) - *hptr = '\0'; - } - ls->histactive = histactive; - ls->histdone = histdone; - ls->stophist = stophist; - ls->hline = chline; - ls->hptr = hptr; - ls->chwords = chwords; - ls->chwordlen = chwordlen; - ls->chwordpos = chwordpos; - ls->hwgetword = hwgetword; - ls->hgetc = hgetc; - ls->hungetc = hungetc; - ls->hwaddc = hwaddc; - ls->hwbegin = hwbegin; - ls->hwend = hwend; - ls->addtoline = addtoline; - ls->hlinesz = hlinesz; - /* - * We save and restore the command stack with history - * as it's visible to the user interactively, so if - * we're preserving history state we'll continue to - * show the current set of commands from input. - */ - ls->cstack = cmdstack; - ls->csp = cmdsp; - - stophist = 0; - chline = NULL; - hptr = NULL; - histactive = 0; - cmdstack = (unsigned char *)zalloc(CMDSTACKSZ); - cmdsp = 0; - } - if (parts & ZCONTEXT_PARSE) { - ls->hdocs = hdocs; - ls->eclen = eclen; - ls->ecused = ecused; - ls->ecnpats = ecnpats; - ls->ecbuf = ecbuf; - ls->ecstrs = ecstrs; - ls->ecsoffs = ecsoffs; - ls->ecssub = ecssub; - ls->ecnfunc = ecnfunc; - ecbuf = NULL; - hdocs = NULL; - } - - ls->next = lstack; - lstack = ls; -} - -/* save context in full */ - -/**/ -mod_export void -lexsave(void) -{ - lexsave_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE); -} - -/* restore context or part therefore */ - -/**/ -mod_export void -lexrestore_partial(int parts) +void +lex_context_save(struct lex_stack *ls, int toplevel) { - struct lexstack *ln = lstack; - - DPUTS(!lstack, "BUG: lexrestore() without lexsave()"); - - queue_signals(); - lstack = lstack->next; - - if (parts & ZCONTEXT_LEX) { - incmdpos = ln->incmdpos; - incond = ln->incond; - incasepat = ln->incasepat; - dbparens = ln->dbparens; - isfirstln = ln->isfirstln; - isfirstch = ln->isfirstch; - lexflags = ln->lexflags; - tok = ln->tok; - isnewlin = ln->isnewlin; - tokstr = ln->tokstr; - zshlextext = ln->zshlextext; - bptr = ln->bptr; - bsiz = ln->bsiz; - len = ln->len; - lex_add_raw = ln->lex_add_raw; - tokstr_raw = ln->tokstr_raw; - bptr_raw = ln->bptr_raw; - bsiz_raw = ln->bsiz_raw; - len_raw = ln->len_raw; - lexstop = ln->lexstop; - toklineno = ln->toklineno; - } - - if (parts & ZCONTEXT_HIST) { - if (!lstack) { - /* Back to top level: don't need special ZLE value */ - DPUTS(ln->hline != zle_chline, "BUG: Ouch, wrong chline for ZLE"); - zle_chline = NULL; - } - histactive = ln->histactive; - histdone = ln->histdone; - stophist = ln->stophist; - chline = ln->hline; - hptr = ln->hptr; - chwords = ln->chwords; - chwordlen = ln->chwordlen; - chwordpos = ln->chwordpos; - hwgetword = ln->hwgetword; - hgetc = ln->hgetc; - hungetc = ln->hungetc; - hwaddc = ln->hwaddc; - hwbegin = ln->hwbegin; - hwend = ln->hwend; - addtoline = ln->addtoline; - hlinesz = ln->hlinesz; - if (cmdstack) - zfree(cmdstack, CMDSTACKSZ); - cmdstack = ln->cstack; - cmdsp = ln->csp; - } - - if (parts & ZCONTEXT_PARSE) { - if (ecbuf) - zfree(ecbuf, eclen); - - hdocs = ln->hdocs; - eclen = ln->eclen; - ecused = ln->ecused; - ecnpats = ln->ecnpats; - ecbuf = ln->ecbuf; - ecstrs = ln->ecstrs; - ecsoffs = ln->ecsoffs; - ecssub = ln->ecssub; - ecnfunc = ln->ecnfunc; - - errflag &= ~ERRFLAG_ERROR; - } - - free(ln); - - unqueue_signals(); + (void)toplevel; + + ls->dbparens = dbparens; + ls->isfirstln = isfirstln; + ls->isfirstch = isfirstch; + ls->lexflags = lexflags; + + ls->tok = tok; + ls->tokstr = tokstr; + ls->zshlextext = zshlextext; + ls->bptr = bptr; + ls->bsiz = bsiz; + ls->len = len; + ls->lex_add_raw = lex_add_raw; + ls->tokstr_raw = tokstr_raw; + ls->bptr_raw = bptr_raw; + ls->bsiz_raw = bsiz_raw; + ls->len_raw = len_raw; + ls->lexstop = lexstop; + ls->toklineno = toklineno; + + tokstr = zshlextext = bptr = NULL; + bsiz = 256; + tokstr_raw = bptr_raw = NULL; + bsiz_raw = len_raw = lex_add_raw = 0; } -/* complete restore context */ +/* restore lexical context */ /**/ mod_export void -lexrestore(void) +lex_context_restore(const struct lex_stack *ls, int toplevel) { - lexrestore_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE); + (void)toplevel; + + dbparens = ls->dbparens; + isfirstln = ls->isfirstln; + isfirstch = ls->isfirstch; + lexflags = ls->lexflags; + tok = ls->tok; + tokstr = ls->tokstr; + zshlextext = ls->zshlextext; + bptr = ls->bptr; + bsiz = ls->bsiz; + len = ls->len; + lex_add_raw = ls->lex_add_raw; + tokstr_raw = ls->tokstr_raw; + bptr_raw = ls->bptr_raw; + bsiz_raw = ls->bsiz_raw; + len_raw = ls->len_raw; + lexstop = ls->lexstop; + toklineno = ls->toklineno; } /**/ @@ -634,9 +435,7 @@ initlextabs(void) void lexinit(void) { - incond = incasepat = nocorrect = - infor = dbparens = lexstop = 0; - incmdpos = 1; + nocorrect = dbparens = lexstop = 0; tok = ENDINPUT; } @@ -1725,7 +1524,7 @@ parsestrnoerr(char *s) { int l = strlen(s), err; - lexsave(); + zcontext_save(); untokenize(s); inpush(dupstring(s), 0, NULL); strinbeg(0); @@ -1737,7 +1536,7 @@ parsestrnoerr(char *s) strinend(); inpop(); DPUTS(cmdsp, "BUG: parsestr: cmdstack not empty."); - lexrestore(); + zcontext_restore(); return err; } @@ -1756,7 +1555,7 @@ parse_subscript(char *s, int sub, int endchar) if (!*s || *s == endchar) return 0; - lexsave(); + zcontext_save(); untokenize(t = dupstring(s)); inpush(t, 0, NULL); strinbeg(0); @@ -1776,7 +1575,7 @@ parse_subscript(char *s, int sub, int endchar) strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty."); - lexrestore(); + zcontext_restore(); return s; } @@ -1794,7 +1593,7 @@ parse_subst_string(char *s) if (!*s || !strcmp(s, nulstring)) return 0; - lexsave(); + zcontext_save(); untokenize(s); inpush(dupstring(s), 0, NULL); strinbeg(0); @@ -1807,7 +1606,7 @@ parse_subst_string(char *s) strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty."); - lexrestore(); + zcontext_restore(); /* Keep any interrupt error status */ errflag = err | (errflag & ERRFLAG_INT); if (ctok == LEXERR) { @@ -1817,7 +1616,7 @@ parse_subst_string(char *s) #ifdef DEBUG /* * Historical note: we used to check here for olen (the value of len - * before lexrestore()) == l, but that's not necessarily the case if + * before zcontext_restore()) == l, but that's not necessarily the case if * we stripped an RCQUOTE. */ if (ctok != STRING || (errflag && !noerrs)) { @@ -2047,7 +1846,7 @@ skipcomm(void) new_len = len; new_bsiz = bsiz; - lexsave_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); + zcontext_save_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); } else { /* * Set up for nested command subsitution, however @@ -2063,7 +1862,7 @@ skipcomm(void) new_len = len_raw; new_bsiz = bsiz_raw; - lexsave_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); + zcontext_save_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); } tokstr_raw = new_tokstr; bsiz_raw = new_bsiz; @@ -2090,7 +1889,7 @@ skipcomm(void) */ new_lexstop = lexstop; - lexrestore_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); + zcontext_restore_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE); if (lex_add_raw) { /* 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(); diff --git a/Src/signals.c b/Src/signals.c index 899f1217b..3950ad1a2 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -1210,7 +1210,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) intrap++; *sigtr |= ZSIG_IGNORED; - lexsave(); + zcontext_save(); /* execsave will save the old trap_return and trap_state */ execsave(); breaks = retflag = 0; @@ -1265,7 +1265,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) new_trap_return = trap_return; execrestore(); - lexrestore(); + zcontext_restore(); if (new_trap_state == TRAP_STATE_FORCE_RETURN && /* zero return from function isn't special */ diff --git a/Src/zsh.h b/Src/zsh.h index 475b7824f..8fb4f977a 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2691,6 +2691,71 @@ struct sortelt { typedef struct sortelt *SortElt; +/*********************************************************/ +/* Structures to save and restore for individual modules */ +/*********************************************************/ + +/* History */ +struct hist_stack { + int histactive; + int histdone; + int stophist; + int hlinesz; + char *hline; + char *hptr; + short *chwords; + int chwordlen; + int chwordpos; + int hwgetword; + int (*hgetc) _((void)); + void (*hungetc) _((int)); + void (*hwaddc) _((int)); + void (*hwbegin) _((int)); + void (*hwend) _((void)); + void (*addtoline) _((int)); + unsigned char *cstack; + int csp; +}; + +/* Lexical analyser */ +struct lex_stack { + int dbparens; + int isfirstln; + int isfirstch; + int lexflags; + enum lextok tok; + char *tokstr; + char *zshlextext; + char *bptr; + int bsiz; + int len; + int lex_add_raw; + char *tokstr_raw; + char *bptr_raw; + int bsiz_raw; + int len_raw; + int lexstop; + zlong toklineno; +}; + +/* Parser */ +struct parse_stack { + struct heredocs *hdocs; + + int incmdpos; + int aliasspaceflag; + int incond; + int inredir; + int incasepat; + int isnewlin; + int infor; + + int eclen, ecused, ecnpats; + Wordcode ecbuf; + Eccstr ecstrs; + int ecsoffs, ecssub, ecnfunc; +}; + /************************/ /* Flags to casemodifiy */ /************************/ diff --git a/Src/zsh.mdd b/Src/zsh.mdd index 9a8c923f9..f0379d2d1 100644 --- a/Src/zsh.mdd +++ b/Src/zsh.mdd @@ -9,7 +9,8 @@ alwayslink=1 # autobins not specified because of alwayslink -objects="builtin.o compat.o cond.o exec.o glob.o hashtable.o hashnameddir.o \ +objects="builtin.o compat.o cond.o context.o \ +exec.o glob.o hashtable.o hashnameddir.o \ hist.o init.o input.o jobs.o lex.o linklist.o loop.o math.o \ mem.o module.o options.o params.o parse.o pattern.o prompt.o signals.o \ signames.o sort.o string.o subst.o text.o utils.o watch.o" -- cgit 1.4.1