mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-28 05:00:59 +01:00
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.
This commit is contained in:
parent
6291d38848
commit
cfd91eac07
15 changed files with 446 additions and 295 deletions
|
|
@ -1,3 +1,12 @@
|
|||
2015-01-09 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 34189: Src/Zle/compcore.c, Src/Zle/compctl.c,
|
||||
Src/Zle/textobjects.c, Src/Zle/zle_tricky.c, Src/builtin.c,
|
||||
Src/context.c, Src/exec.c, Src/hist.c, Src/init.c, Src/lex.c,
|
||||
Src/parse.c, Src/signals.c, Src/zsh.h, Src/zsh.mdd:
|
||||
vain attempt to make context save and restore neater and
|
||||
control the status variables thereby managed.
|
||||
|
||||
2015-01-09 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 34182: Doc/Zsh/mod_files.yo: to add zf_* builtins you can
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
116
Src/context.c
Normal file
116
Src/context.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
88
Src/hist.c
88
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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
271
Src/lex.c
271
Src/lex.c
|
|
@ -203,82 +203,20 @@ 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)
|
||||
void
|
||||
lex_context_save(struct lex_stack *ls, int toplevel)
|
||||
{
|
||||
struct lexstack *ls;
|
||||
(void)toplevel;
|
||||
|
||||
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;
|
||||
|
|
@ -296,170 +234,33 @@ lexsave_partial(int parts)
|
|||
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 */
|
||||
/* restore lexical context */
|
||||
|
||||
/**/
|
||||
mod_export void
|
||||
lexsave(void)
|
||||
lex_context_restore(const struct lex_stack *ls, int toplevel)
|
||||
{
|
||||
lexsave_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE);
|
||||
}
|
||||
(void)toplevel;
|
||||
|
||||
/* restore context or part therefore */
|
||||
|
||||
/**/
|
||||
mod_export void
|
||||
lexrestore_partial(int parts)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
/* complete restore context */
|
||||
|
||||
/**/
|
||||
mod_export void
|
||||
lexrestore(void)
|
||||
{
|
||||
lexrestore_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE);
|
||||
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) {
|
||||
/*
|
||||
|
|
|
|||
81
Src/parse.c
81
Src/parse.c
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
65
Src/zsh.h
65
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 */
|
||||
/************************/
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue