mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix compile/regress fails on compiling without SHOPT_* options
Many compile-time options were broken so that they could not be
turned off without causing compile errors and/or regression test
failures. This commit now allows the following to be disabled:
SHOPT_2DMATCH # two dimensional ${.sh.match} for ${var//pat/str}
SHOPT_BGX # one SIGCHLD trap per completed job
SHOPT_BRACEPAT # C-shell {...,...} expansions (, required)
SHOPT_ESH # emacs/gmacs edit mode
SHOPT_HISTEXPAND # csh-style history file expansions
SHOPT_MULTIBYTE # multibyte character handling
SHOPT_NAMESPACE # allow namespaces
SHOPT_STATS # add .sh.stats variable
SHOPT_VSH # vi edit mode
The following still break ksh when disabled:
SHOPT_FIXEDARRAY # fixed dimension indexed array
SHOPT_RAWONLY # make viraw the only vi mode
SHOPT_TYPEDEF # enable typeset type definitions
Compiling without SHOPT_RAWONLY just gives four regression test
failures in pty.sh, but turning off SHOPT_FIXEDARRAY and
SHOPT_TYPEDEF causes compilation to fail. I've managed to tweak the
code to make it compile without those two options, but then dozens
of regression test failures occur, often in things nothing directly
to do with those options. It looks like the separation between the
code for these options and the rest was never properly maintained.
Making it possible to disable SHOPT_FIXEDARRAY and SHOPT_TYPEDEF
may involve major refactoring and testing and may not be worth it.
This commit has far too many tweaks to list. Notables fixes are:
src/cmd/ksh93/data/builtins.c,
src/cmd/ksh93/data/options.c:
- Do not compile in the shell options and documentation for
disabled features (braceexpand, emacs/gmacs, vi/viraw), so the
shell is not left with no-op options and inaccurate self-doc.
src/cmd/ksh93/data/lexstates.c:
- Comment the state tables to associte them with their IDs.
- In the ST_MACRO table (sh_lexstate9[]), do not make the S_BRACE
state for position 123 (ASCII for '{') conditional upon
SHOPT_BRACEPAT (brace expansion), otherwise disabling this causes
glob patterns of the form {3}(x) (matching 3 x'es) to stop
working as well -- and that is ksh globbing, not brace expansion.
src/cmd/ksh93/edit/edit.c: ed_read():
- Fixed a bug: SIGWINCH was not handled by the gmacs edit mode.
src/cmd/ksh93/sh/name.c: nv_putval():
- The -L/-R left/right adjustment options to typeset do not count
zero-width characters. This is the behaviour with SHOPT_MULTIBYTE
enabled, regardless of locale. Of course, what a zero-width
character is depends on the locale, but control characters are
always considered zero-width. So, to avoid a regression, add some
fallback code for non-SHOPT_MULTIBYTE builds that skips ASCII
control characters (as per iscntrl(3)) so they are still
considered to have zero width.
src/cmd/ksh93/tests/shtests:
- Export the SHOPT_* macros from SHOPT.sh to the tests as
environment variables, so the tests can check for them and decide
whether or how to run tests based on the compile-time options
that the tested binary was presumably compiled with.
- Do not run the C.UTF-8 tests if SHOPT_MULTIBYTE is not enabled.
src/cmd/ksh93/tests/*.sh:
- Add a bunch of checks for SHOPT_* env vars. Since most should
have a value 0 (off) or 1 (on), the form ((SHOPT_FOO)) is a
convenient way to use them as arithmetic booleans.
.github/workflows/ci.yml:
- Make GitHub do more testing: run two locale tests (Dutch and
Japanese UTF-8 locales), then disable all the SHOPTs that we can
currently disable, recompile ksh, and run the tests again.
This commit is contained in:
parent
a9d77bba40
commit
2182ecfa08
40 changed files with 413 additions and 157 deletions
|
|
@ -40,16 +40,6 @@
|
|||
#if SHOPT_KIA || SHOPT_DEVFD
|
||||
# include "io.h"
|
||||
#endif
|
||||
#if SHOPT_PFSH
|
||||
# define PFSHOPT "P"
|
||||
#else
|
||||
# define PFSHOPT
|
||||
#endif
|
||||
#if SHOPT_HISTEXPAND
|
||||
# define HFLAG "H"
|
||||
#else
|
||||
# define HFLAG ""
|
||||
#endif
|
||||
|
||||
#define SORT 1
|
||||
#define PRINT 2
|
||||
|
|
@ -57,7 +47,19 @@
|
|||
static char *null;
|
||||
|
||||
/* The following order is determined by sh_optset */
|
||||
static const char optksh[] = PFSHOPT "DircabefhkmnpstuvxBCGEl" HFLAG;
|
||||
static const char optksh[] =
|
||||
#if SHOPT_PFSH
|
||||
"P"
|
||||
#endif
|
||||
"Dircabefhkmnpstuvx"
|
||||
#if SHOPT_BRACEPAT
|
||||
"B"
|
||||
#endif
|
||||
"CGEl"
|
||||
#if SHOPT_HISTEXPAND
|
||||
"H"
|
||||
#endif
|
||||
;
|
||||
static const int flagval[] =
|
||||
{
|
||||
#if SHOPT_PFSH
|
||||
|
|
@ -66,8 +68,11 @@ static const int flagval[] =
|
|||
SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
|
||||
SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
|
||||
SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG,
|
||||
SH_NOUNSET, SH_VERBOSE, SH_XTRACE, SH_BRACEEXPAND, SH_NOCLOBBER,
|
||||
SH_GLOBSTARS, SH_RC, SH_LOGIN_SHELL,
|
||||
SH_NOUNSET, SH_VERBOSE, SH_XTRACE,
|
||||
#if SHOPT_BRACEPAT
|
||||
SH_BRACEEXPAND,
|
||||
#endif
|
||||
SH_NOCLOBBER, SH_GLOBSTARS, SH_RC, SH_LOGIN_SHELL,
|
||||
#if SHOPT_HISTEXPAND
|
||||
SH_HISTEXPAND,
|
||||
#endif
|
||||
|
|
@ -231,12 +236,21 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
}
|
||||
if(f)
|
||||
{
|
||||
#if SHOPT_ESH && SHOPT_VSH
|
||||
if(o==SH_VI || o==SH_EMACS || o==SH_GMACS)
|
||||
{
|
||||
off_option(&newflags,SH_VI);
|
||||
off_option(&newflags,SH_EMACS);
|
||||
off_option(&newflags,SH_GMACS);
|
||||
}
|
||||
#elif SHOPT_ESH
|
||||
if(o==SH_EMACS || o==SH_GMACS)
|
||||
{
|
||||
off_option(&newflags,SH_EMACS);
|
||||
off_option(&newflags,SH_GMACS);
|
||||
}
|
||||
|
||||
#endif /* SHOPT_ESH && SHOPT_VSH */
|
||||
on_option(&newflags,o);
|
||||
off_option(&ap->sh->offoptions,o);
|
||||
}
|
||||
|
|
@ -567,7 +581,7 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
|
|||
sfputc(sfstdout,'\n');
|
||||
return;
|
||||
}
|
||||
#if SHOPT_RAWONLY
|
||||
#if SHOPT_VSH && SHOPT_RAWONLY
|
||||
on_option(&oflags,SH_VIRAW);
|
||||
#endif
|
||||
if(!(mode&(PRINT_ALL|PRINT_VERBOSE))) /* only print set options */
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@
|
|||
#include "io.h"
|
||||
#include "path.h"
|
||||
|
||||
#if !SHOPT_BRACEPAT
|
||||
# define SHOPT_BRACEPAT 0
|
||||
#endif
|
||||
|
||||
#if KSHELL
|
||||
# define argbegin argnxt.cp
|
||||
static const char *sufstr;
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ void sh_chktrap(Shell_t* shp)
|
|||
}
|
||||
if(shp->sigflag[SIGALRM]&SH_SIGALRM)
|
||||
sh_timetraps(shp);
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if((shp->sigflag[SIGCHLD]&SH_SIGTRAP) && shp->st.trapcom[SIGCHLD])
|
||||
job_chldtrap(shp,shp->st.trapcom[SIGCHLD],1);
|
||||
#endif /* SHOPT_BGX */
|
||||
|
|
@ -421,7 +421,7 @@ void sh_chktrap(Shell_t* shp)
|
|||
{
|
||||
if(sig==cursig)
|
||||
continue;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if(sig==SIGCHLD)
|
||||
continue;
|
||||
#endif /* SHOPT_BGX */
|
||||
|
|
@ -626,9 +626,17 @@ void sh_done(void *ptr, register int sig)
|
|||
sh_accend();
|
||||
#endif /* SHOPT_ACCT */
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
if(mbwide()||sh_isoption(SH_EMACS)||sh_isoption(SH_VI)||sh_isoption(SH_GMACS))
|
||||
tty_cooked(-1);
|
||||
if(mbwide()
|
||||
#if SHOPT_ESH
|
||||
|| sh_isoption(SH_EMACS)
|
||||
|| sh_isoption(SH_GMACS)
|
||||
#endif
|
||||
#if SHOPT_VSH
|
||||
|| sh_isoption(SH_VI)
|
||||
#endif
|
||||
)
|
||||
tty_cooked(-1);
|
||||
#endif /* SHOPT_VSH || SHOPT_ESH */
|
||||
#ifdef JOBS
|
||||
if((sh_isoption(SH_INTERACTIVE) && shp->login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
|
||||
job_walk(sfstderr, job_hup, SIGHUP, NIL(char**));
|
||||
|
|
|
|||
|
|
@ -178,8 +178,10 @@ typedef struct _init_
|
|||
Namfun_t CDPATH_init;
|
||||
Namfun_t SHELL_init;
|
||||
Namfun_t ENV_init;
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
Namfun_t VISUAL_init;
|
||||
Namfun_t EDITOR_init;
|
||||
#endif
|
||||
Namfun_t HISTFILE_init;
|
||||
Namfun_t HISTSIZE_init;
|
||||
Namfun_t OPTINDEX_init;
|
||||
|
|
@ -227,6 +229,7 @@ static char *nospace(int unused)
|
|||
return(NIL(char*));
|
||||
}
|
||||
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
/* Trap for VISUAL and EDITOR variables */
|
||||
static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
|
||||
{
|
||||
|
|
@ -239,22 +242,34 @@ static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
|
|||
goto done;
|
||||
/* turn on vi or emacs option if editor name is either*/
|
||||
cp = path_basename(cp);
|
||||
#if SHOPT_VSH
|
||||
if(strmatch(cp,"*[Vv][Ii]*"))
|
||||
newopt=SH_VI;
|
||||
else if(strmatch(cp,"*gmacs*"))
|
||||
#endif
|
||||
#if SHOPT_VSH && SHOPT_ESH
|
||||
else
|
||||
#endif
|
||||
#if SHOPT_ESH
|
||||
if(strmatch(cp,"*gmacs*"))
|
||||
newopt=SH_GMACS;
|
||||
else if(strmatch(cp,"*macs*"))
|
||||
newopt=SH_EMACS;
|
||||
#endif
|
||||
if(newopt)
|
||||
{
|
||||
#if SHOPT_VSH
|
||||
sh_offoption(SH_VI);
|
||||
#endif
|
||||
#if SHOPT_ESH
|
||||
sh_offoption(SH_EMACS);
|
||||
sh_offoption(SH_GMACS);
|
||||
#endif
|
||||
sh_onoption(newopt);
|
||||
}
|
||||
done:
|
||||
nv_putv(np, val, flags, fp);
|
||||
}
|
||||
#endif /* SHOPT_VSH || SHOPT_ESH */
|
||||
|
||||
/* Trap for HISTFILE and HISTSIZE variables */
|
||||
static void put_history(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
|
||||
|
|
@ -727,11 +742,11 @@ void sh_setmatch(Shell_t *shp,const char *v, int vsize, int nmatch, regoff_t mat
|
|||
Namarr_t *ap = nv_arrayptr(SH_MATCHNOD);
|
||||
Namarr_t *ap_save = ap;
|
||||
shp->subshell = 0;
|
||||
#ifndef SHOPT_2DMATCH
|
||||
#if !SHOPT_2DMATCH
|
||||
index = 0;
|
||||
#else
|
||||
if(index==0)
|
||||
#endif /* SHOPT_2DMATCH */
|
||||
#endif /* !SHOPT_2DMATCH */
|
||||
{
|
||||
if(ap->hdr.next != &mp->hdr)
|
||||
{
|
||||
|
|
@ -759,7 +774,7 @@ void sh_setmatch(Shell_t *shp,const char *v, int vsize, int nmatch, regoff_t mat
|
|||
mp->v = v;
|
||||
mp->first = match[0];
|
||||
}
|
||||
#ifdef SHOPT_2DMATCH
|
||||
#if SHOPT_2DMATCH
|
||||
else
|
||||
{
|
||||
if(index==1)
|
||||
|
|
@ -882,7 +897,9 @@ static const Namdisc_t SH_VERSION_disc = { 0, 0, get_version, nget_version };
|
|||
static const Namdisc_t IFS_disc = { sizeof(struct ifs), put_ifs, get_ifs };
|
||||
const Namdisc_t RESTRICTED_disc = { sizeof(Namfun_t), put_restricted };
|
||||
static const Namdisc_t CDPATH_disc = { sizeof(Namfun_t), put_cdpath };
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
static const Namdisc_t EDITOR_disc = { sizeof(Namfun_t), put_ed };
|
||||
#endif
|
||||
static const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history };
|
||||
static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex };
|
||||
static const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds };
|
||||
|
|
@ -1416,7 +1433,7 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
|
|||
/* set[ug]id scripts require the -p flag */
|
||||
if(shp->gd->userid!=shp->gd->euserid || shp->gd->groupid!=shp->gd->egroupid)
|
||||
{
|
||||
#ifdef SHOPT_P_SUID
|
||||
#if SHOPT_P_SUID
|
||||
/* require sh -p to run setuid and/or setgid */
|
||||
if(!sh_isoption(SH_PRIVILEGED) && shp->gd->userid >= SHOPT_P_SUID)
|
||||
{
|
||||
|
|
@ -1548,14 +1565,18 @@ int sh_reinit(char *argv[])
|
|||
#endif /* SHOPT_NAMESPACE */
|
||||
if(sh_isoption(SH_TRACKALL))
|
||||
on_option(&opt,SH_TRACKALL);
|
||||
#if SHOPT_ESH
|
||||
if(sh_isoption(SH_EMACS))
|
||||
on_option(&opt,SH_EMACS);
|
||||
if(sh_isoption(SH_GMACS))
|
||||
on_option(&opt,SH_GMACS);
|
||||
#endif
|
||||
#if SHOPT_VSH
|
||||
if(sh_isoption(SH_VI))
|
||||
on_option(&opt,SH_VI);
|
||||
if(sh_isoption(SH_VIRAW))
|
||||
on_option(&opt,SH_VIRAW);
|
||||
#endif
|
||||
shp->options = opt;
|
||||
/* set up new args */
|
||||
if(argv)
|
||||
|
|
@ -1607,7 +1628,7 @@ Namfun_t *nv_cover(register Namval_t *np)
|
|||
|
||||
static const char *shdiscnames[] = { "tilde", 0};
|
||||
|
||||
#ifdef SHOPT_STATS
|
||||
#if SHOPT_STATS
|
||||
struct Stats
|
||||
{
|
||||
Namfun_t hdr;
|
||||
|
|
@ -1735,10 +1756,12 @@ static Init_t *nv_init(Shell_t *shp)
|
|||
ip->SHELL_init.nofree = 1;
|
||||
ip->ENV_init.disc = &RESTRICTED_disc;
|
||||
ip->ENV_init.nofree = 1;
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
ip->VISUAL_init.disc = &EDITOR_disc;
|
||||
ip->VISUAL_init.nofree = 1;
|
||||
ip->EDITOR_init.disc = &EDITOR_disc;
|
||||
ip->EDITOR_init.nofree = 1;
|
||||
#endif
|
||||
ip->HISTFILE_init.disc = &HISTFILE_disc;
|
||||
ip->HISTFILE_init.nofree = 1;
|
||||
ip->HISTSIZE_init.disc = &HISTFILE_disc;
|
||||
|
|
@ -1781,8 +1804,10 @@ static Init_t *nv_init(Shell_t *shp)
|
|||
nv_stack(CDPNOD, &ip->CDPATH_init);
|
||||
nv_stack(SHELLNOD, &ip->SHELL_init);
|
||||
nv_stack(ENVNOD, &ip->ENV_init);
|
||||
#if SHOPT_VSH || SHOPT_ESH
|
||||
nv_stack(VISINOD, &ip->VISUAL_init);
|
||||
nv_stack(EDITNOD, &ip->EDITOR_init);
|
||||
#endif
|
||||
nv_stack(HISTFILE, &ip->HISTFILE_init);
|
||||
nv_stack(HISTSIZE, &ip->HISTSIZE_init);
|
||||
nv_stack(OPTINDNOD, &ip->OPTINDEX_init);
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ struct back_save
|
|||
#define P_COREDUMP 0100
|
||||
#define P_DISOWN 0200
|
||||
#define P_FG 0400
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
#define P_BG 01000
|
||||
#endif /* SHOPT_BGX */
|
||||
|
||||
|
|
@ -194,7 +194,7 @@ static struct back_save bck;
|
|||
|
||||
typedef int (*Waitevent_f)(int,long,int);
|
||||
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
void job_chldtrap(Shell_t *shp, const char *trap, int unpost)
|
||||
{
|
||||
register struct process *pw,*pwnext;
|
||||
|
|
@ -404,7 +404,7 @@ int job_reap(register int sig)
|
|||
if(WEXITSTATUS(wstat) > pw->p_exitmin)
|
||||
pw->p_exit = WEXITSTATUS(wstat);
|
||||
}
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if((pw->p_flag&P_DONE) && (pw->p_flag&P_BG))
|
||||
{
|
||||
job.numbjob--;
|
||||
|
|
@ -443,7 +443,7 @@ int job_reap(register int sig)
|
|||
if(!px && sh_isoption(SH_INTERACTIVE))
|
||||
tcsetpgrp(JOBTTY,job.mypid);
|
||||
}
|
||||
#ifndef SHOPT_BGX
|
||||
#if !SHOPT_BGX
|
||||
if(!shp->intrap && shp->st.trapcom[SIGCHLD] && pid>0 && (pwfg!=job_bypid(pid)))
|
||||
{
|
||||
shp->sigflag[SIGCHLD] |= SH_SIGTRAP;
|
||||
|
|
@ -454,7 +454,7 @@ int job_reap(register int sig)
|
|||
if(errno==ECHILD)
|
||||
{
|
||||
errno = oerrno;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
job.numbjob = 0;
|
||||
#endif /* SHOPT_BGX */
|
||||
nochild = 1;
|
||||
|
|
@ -1188,7 +1188,7 @@ void job_clear(void)
|
|||
init_savelist();
|
||||
job.pwlist = NIL(struct process*);
|
||||
job.numpost=0;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
job.numbjob = 0;
|
||||
#endif /* SHOPT_BGX */
|
||||
job.waitall = 0;
|
||||
|
|
@ -1210,7 +1210,7 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
|
|||
{
|
||||
register struct process *pw;
|
||||
register History_t *hp = shp->gd->hist_ptr;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
int val,bg=0;
|
||||
#else
|
||||
int val;
|
||||
|
|
@ -1222,7 +1222,7 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
|
|||
return(0);
|
||||
}
|
||||
job_lock();
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if(join==1)
|
||||
{
|
||||
join = 0;
|
||||
|
|
@ -1314,7 +1314,7 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
|
|||
else
|
||||
pw->p_flag |= (P_DONE|P_NOTIFY);
|
||||
}
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if(bg)
|
||||
{
|
||||
if(pw->p_flag&P_DONE)
|
||||
|
|
@ -1610,7 +1610,7 @@ int job_switch(register struct process *pw,int bgflag)
|
|||
{
|
||||
sfprintf(outfile,"[%d]\t",(int)pw->p_job);
|
||||
sh.bckpid = pw->p_pid;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
pw->p_flag |= P_BG;
|
||||
#endif
|
||||
msg = "&";
|
||||
|
|
@ -1634,7 +1634,7 @@ int job_switch(register struct process *pw,int bgflag)
|
|||
}
|
||||
job.waitall = 1;
|
||||
pw->p_flag |= P_FG;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
pw->p_flag &= ~P_BG;
|
||||
#endif
|
||||
job_wait(pw->p_pid);
|
||||
|
|
@ -1703,7 +1703,7 @@ static struct process *job_unpost(register struct process *pwtop,int notify)
|
|||
pwtop = pw = job_byjid((int)pwtop->p_job);
|
||||
if(!pw)
|
||||
return(0);
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if(pw->p_flag&P_BG)
|
||||
return(pw);
|
||||
#endif /* SHOPT_BGX */
|
||||
|
|
|
|||
|
|
@ -1252,12 +1252,14 @@ int sh_lex(Lex_t* lp)
|
|||
/* check for reserved word { or } */
|
||||
if(lp->lex.reservok && state[n]==S_BREAK && isfirst)
|
||||
break;
|
||||
#if SHOPT_BRACEPAT
|
||||
if(sh_isoption(SH_BRACEEXPAND) && c==LBRACE && !assignment && state[n]!=S_BREAK
|
||||
&& !lp->lex.incase && !lp->lex.intest
|
||||
&& !lp->lex.skipword)
|
||||
{
|
||||
wordflags |= ARG_EXP;
|
||||
}
|
||||
#endif
|
||||
if(c==RBRACE && n==LPAREN)
|
||||
goto epat;
|
||||
break;
|
||||
|
|
@ -1892,8 +1894,10 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
|
|||
sfputc(sp,'\\');
|
||||
}
|
||||
}
|
||||
#if SHOPT_MULTIBYTE
|
||||
if(LEN < 1)
|
||||
LEN = 1;
|
||||
#endif
|
||||
bufp = fcseek(-LEN);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -508,8 +508,10 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
sfputc(stkp,ESCAPE);
|
||||
break;
|
||||
}
|
||||
#if SHOPT_BRACEPAT
|
||||
else if(sh_isoption(SH_BRACEEXPAND) && mp->pattern==4 && (*cp==',' || *cp==LBRACE || *cp==RBRACE || *cp=='.'))
|
||||
break;
|
||||
#endif
|
||||
else if(mp->split && endch && !mp->quote && !mp->lit)
|
||||
{
|
||||
if(c)
|
||||
|
|
@ -763,15 +765,21 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
case S_BRACE:
|
||||
if(!(mp->quote || mp->lit))
|
||||
{
|
||||
#if SHOPT_BRACEPAT
|
||||
mp->patfound = mp->split && sh_isoption(SH_BRACEEXPAND);
|
||||
#else
|
||||
mp->patfound = 0;
|
||||
#endif
|
||||
brace++;
|
||||
}
|
||||
pattern:
|
||||
if(!mp->pattern || !(mp->quote || mp->lit))
|
||||
{
|
||||
/* mark beginning of {a,b} */
|
||||
#if SHOPT_BRACEPAT
|
||||
if(n==S_BRACE && endch==0 && mp->pattern)
|
||||
mp->pattern=4;
|
||||
#endif
|
||||
if(n==S_SLASH && mp->pattern==2)
|
||||
mp->pattern=3;
|
||||
break;
|
||||
|
|
@ -1102,7 +1110,7 @@ retry1:
|
|||
{
|
||||
if(c=='#')
|
||||
type = M_SIZE;
|
||||
#ifdef SHOPT_TYPEDEF
|
||||
#if SHOPT_TYPEDEF
|
||||
else if(c=='@')
|
||||
{
|
||||
type = M_TYPE;
|
||||
|
|
@ -1410,7 +1418,7 @@ retry1:
|
|||
if(ap && !mp->dotdot && !(ap->nelem&ARRAY_UNDEF))
|
||||
addsub = 1;
|
||||
}
|
||||
#ifdef SHOPT_TYPEDEF
|
||||
#if SHOPT_TYPEDEF
|
||||
else if(type==M_TYPE)
|
||||
{
|
||||
Namval_t *nq = nv_type(np);
|
||||
|
|
|
|||
|
|
@ -1053,8 +1053,15 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
|
|||
}
|
||||
else
|
||||
cp = sp;
|
||||
if((c = *cp)=='.' || (c=='[' && nv_isarray(np)) || (n&ARRAY_FILL) || ((ap || (flags&NV_ASSIGN)) && (flags&NV_ARRAY)))
|
||||
|
||||
if((c = *cp)=='.'
|
||||
|| (c=='[' && nv_isarray(np))
|
||||
|| (n&ARRAY_FILL)
|
||||
|| ((
|
||||
#if SHOPT_FIXEDARRAY
|
||||
ap ||
|
||||
#endif
|
||||
(flags&NV_ASSIGN)) && (flags&NV_ARRAY)))
|
||||
{
|
||||
int m = cp-sp;
|
||||
sub = m?nv_getsub(np):0;
|
||||
|
|
@ -1839,6 +1846,18 @@ void nv_putval(register Namval_t *np, const char *string, int flags)
|
|||
#if SHOPT_MULTIBYTE
|
||||
if(size)
|
||||
size = ja_size((char*)sp,size,nv_isattr(np,NV_RJUST|NV_ZFILL));
|
||||
#else
|
||||
/* fallback: consider control characters to have zero width */
|
||||
if(size)
|
||||
{
|
||||
char *c = (char*)sp;
|
||||
int s = size;
|
||||
for( ; *c && s; c++)
|
||||
if(iscntrl(*c))
|
||||
size++;
|
||||
else
|
||||
s--;
|
||||
}
|
||||
#endif /* SHOPT_MULTIBYTE */
|
||||
}
|
||||
if(!up->cp || *up->cp==0)
|
||||
|
|
|
|||
|
|
@ -752,12 +752,14 @@ static void outval(char *name, const char *vname, struct Walk *wp)
|
|||
{
|
||||
Namarr_t *ap;
|
||||
nv_attribute(np,wp->out,"typeset",'=');
|
||||
#if SHOPT_FIXEDARRAY
|
||||
if((ap=nv_arrayptr(np)) && ap->fixed)
|
||||
{
|
||||
sfprintf(wp->out,"%s",name);
|
||||
nv_arrfixed(np,wp->out,0,(char*)0);
|
||||
sfputc(wp->out,';');
|
||||
}
|
||||
#endif
|
||||
}
|
||||
nv_outname(wp->out,name,-1);
|
||||
if((np->nvalue.cp && np->nvalue.cp!=Empty) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE)) || nv_isvtree(np))
|
||||
|
|
|
|||
|
|
@ -1240,7 +1240,12 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
int jmpval, save_prompt;
|
||||
int was_nofork = execflg?sh_isstate(SH_NOFORK):0;
|
||||
struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt));
|
||||
volatile unsigned long was_vi=0, was_emacs=0, was_gmacs=0;
|
||||
#if SHOPT_VSH
|
||||
volatile unsigned long was_vi=0;
|
||||
#endif
|
||||
#if SHOPT_ESH
|
||||
volatile unsigned long was_emacs=0, was_gmacs=0;
|
||||
#endif
|
||||
struct stat statb;
|
||||
bp = &shp->bltindata;
|
||||
save_ptr = bp->ptr;
|
||||
|
|
@ -1252,12 +1257,16 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
* disable editors for built-in
|
||||
* versions of commands on PATH
|
||||
*/
|
||||
#if SHOPT_VSH
|
||||
was_vi = sh_isoption(SH_VI);
|
||||
sh_offoption(SH_VI);
|
||||
#endif
|
||||
#if SHOPT_ESH
|
||||
was_emacs = sh_isoption(SH_EMACS);
|
||||
was_gmacs = sh_isoption(SH_GMACS);
|
||||
sh_offoption(SH_VI);
|
||||
sh_offoption(SH_EMACS);
|
||||
sh_offoption(SH_GMACS);
|
||||
#endif
|
||||
}
|
||||
if(execflg)
|
||||
sh_onstate(SH_NOFORK);
|
||||
|
|
@ -1392,12 +1401,17 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
shp->bltinfun = 0;
|
||||
if(buffp->olist)
|
||||
free_list(buffp->olist);
|
||||
#if SHOPT_VSH
|
||||
if(was_vi)
|
||||
sh_onoption(SH_VI);
|
||||
else if(was_emacs)
|
||||
else
|
||||
#endif
|
||||
#if SHOPT_ESH
|
||||
if(was_emacs)
|
||||
sh_onoption(SH_EMACS);
|
||||
else if(was_gmacs)
|
||||
sh_onoption(SH_GMACS);
|
||||
#endif
|
||||
if(scope)
|
||||
sh_unscope(shp);
|
||||
bp->ptr = (void*)save_ptr;
|
||||
|
|
@ -1555,7 +1569,7 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
job.parent=parent=0;
|
||||
else
|
||||
{
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
int maxjob;
|
||||
if(((type&(FAMP|FINT)) == (FAMP|FINT)) && (maxjob=nv_getnum(JOBMAXNOD))>0)
|
||||
{
|
||||
|
|
@ -2856,7 +2870,7 @@ pid_t _sh_fork(Shell_t *shp,register pid_t parent,int flags,int *jobid)
|
|||
shp->cpid = parent;
|
||||
if(!postid && job.curjobid && (flags&FPOU))
|
||||
postid = job.curpgid;
|
||||
#ifdef SHOPT_BGX
|
||||
#if SHOPT_BGX
|
||||
if(!postid && (flags&(FAMP|FINT)) == (FAMP|FINT))
|
||||
postid = 1;
|
||||
myjob = job_post(shp,parent,postid);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue