Skip to content

Commit

Permalink
Further modernise the stk(3) stack routines (re: f619b48)
Browse files Browse the repository at this point in the history
*** Void pointers ***

The stk(3) interface used char pointers throughout for K&R C and
C++ compatibility. I gave up all pretense of that long ago (see
a34e831) and we now use C89/C90 as our lowest common denominator,
so we're allowed to use void pointers.

The stkalloc(), stkset(), stkseek() and stkfreeze() functions now
return void* instead of char*. This should compatible with old code
as implicit typecasts are done. I scanned all the uses of these in
current code as well as the complete ast-open-history repo and
didn't find problems, nor does 'clang -Wall' throw any warnings.

So, no changes should be required. However, this change does allow
eliminating a lot of verbose/annoying typecasts from the code, as
void pointers can be assigned/passed to all sorts of types. This
commit removes those explicit typecasts, improving code legibility.

The stkcopy() and stkptr() functions continue to return char*, as
the first is purely for copying strings and the second's result is
often dereferenced directly to read individual bytes on the stack.

*** Deprecate/disuse stkinstall() ***

The old stak(3) interface did not pass stack pointers to every
function, so to use multiple stacks, one had to be "installed"
(activated) and there was only one "active" stack at the time. The
new interface has stkinstall() for backward compatibility with this
practice; it updates the stack that stkstd refers to. But this is
completely redundant as it's much more efficient to simply change
the pointer passed to the stack functions. So stkinstall() is
deprecated and its use replaced accordingly in the following files:
- src/lib/libast/misc/glob.c
- src/cmd/ksh93/sh/parse.c
- src/cmd/ksh93/sh/trestore.c

*** Add stkoverflow() ***

In typical AT&T fashion, stkinstall() had another, unrelated
function: set a pointer to a char* function called when the system
runs out of memory to allocate new stack frames. It can either find
memory somewhere and return a pointer, or error out. stkinstall()
did not allow unsetting this function pointer to restore the
default. This commit adds a replacement stkoverflow() function that
sets this function (now of type void*) or restores the default.
(The unset functionality is currently unused but may come in handy
someday and in any case it's trivial.)
This is currently used in:
- src/cmd/ksh93/sh/init.c

*** Bump libast API version ***

In src/lib/libast/features/api, the libast API version is bumped to
20240227 due to the changes above.

*** Rework stk(3) manual page ***

Rewrote parts to match current practice, e.g., removed references
to "the active stack" which never really applied to stk(3).

*** Restore stak.h ***

Perhaps it was overzealous to remove that in the referenced commit.
It's a small header file that simply maps the old stak(3) interface
onto stk(3) using some #defines. It remains unused, but the cost of
having it is negligible and restoring it restores compatbility with
old code we might want to test or backport at some point.
  • Loading branch information
McDutchie committed Feb 27, 2024
1 parent 6628b52 commit 6465cfc
Show file tree
Hide file tree
Showing 37 changed files with 316 additions and 257 deletions.
4 changes: 2 additions & 2 deletions src/cmd/ksh93/bltins/cd_pwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -171,7 +171,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
#endif /* _WINIX */
if(*stkptr(sh.stk,PATH_OFFSET)!='/')
{
char *last=(char*)stkfreeze(sh.stk,1);
char *last = stkfreeze(sh.stk,1);
stkseek(sh.stk,PATH_OFFSET);
sfputr(sh.stk,oldpwd,-1);
/* don't add '/' if oldpwd is / itself */
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/ksh93/bltins/getopts.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -41,7 +41,7 @@ static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
#endif /* SHOPT_NAMESPACE */
{
int savtop = stktell(stkp);
char *savptr = stkfreeze(stkp,0);
void *savptr = stkfreeze(stkp,0);
sfputc(stkp,'$');
sfputc(stkp,'(');
sfputr(stkp,s,')');
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/ksh93/bltins/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -665,7 +665,7 @@ int sh_access(const char *name, int mode)
maxgroups = (int)astconf_long(CONF_NGROUPS_MAX);
}
}
groups = (gid_t*)stkalloc(sh.stk,(maxgroups+1)*sizeof(gid_t));
groups = stkalloc(sh.stk,(maxgroups+1)*sizeof(gid_t));
n = getgroups(maxgroups,groups);
while(--n >= 0)
{
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/ksh93/bltins/typeset.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ int b_typeset(int argc,char *argv[],Shbltin_t *context)
}
else if(argv[0][0] != 't') /* not <t>ypeset */
{
char **new_argv = (char **)stkalloc(sh.stk, (argc + 2) * sizeof(char*));
char **new_argv = stkalloc(sh.stk, (argc + 2) * sizeof(char*));
error_info.id = new_argv[0] = SYSTYPESET->nvname;
if(argv[0][0] == 'a') /* <a>utoload == typeset -fu */
new_argv[1] = "-fu";
Expand Down Expand Up @@ -1607,7 +1607,7 @@ static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tda
if(flag==NV_LTOU || flag==NV_UTOL)
tp->scanmask |= NV_UTOL|NV_LTOU;
namec = nv_scan(root, nullscan, tp, tp->scanmask, flag&~NV_IARRAY);
argv = tp->argnam = (char**)stkalloc(sh.stk,(namec+1)*sizeof(char*));
argv = tp->argnam = stkalloc(sh.stk,(namec+1)*sizeof(char*));
namec = nv_scan(root, pushname, tp, tp->scanmask, flag&~NV_IARRAY);
if(mbcoll())
strsort(argv,namec,strcoll);
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/ksh93/edit/completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
ep->e_nlist = 0;
}
}
comptr = (struct comnod*)stkalloc(sh.stk,sizeof(struct comnod));
ap = (struct argnod*)stkseek(sh.stk,ARGVAL);
comptr = stkalloc(sh.stk,sizeof(struct comnod));
ap = stkseek(sh.stk,ARGVAL);
#if SHOPT_MULTIBYTE
{
int c = *cur;
Expand Down Expand Up @@ -368,7 +368,7 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
}
if(addstar)
sfputc(sh.stk,addstar);
ap = (struct argnod*)stkfreeze(sh.stk,1);
ap = stkfreeze(sh.stk,1);
}
if(mode!='*')
sh_onoption(SH_MARKDIRS);
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/features/externs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ tst note{ determining default number of extra bytes per argument for arguments l
int bytec;

error_info.id="_arg_extrabytes test (child)";
argv = (char **)stkalloc(stkstd, (argmax / 2 + 1) * sizeof(char*));
argv = stkalloc(stkstd, (argmax / 2 + 1) * sizeof(char*));
argc = bytec = 0;
while(bytec < argmax)
{
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/ksh93/sh/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ char **sh_argbuild(int *nargs, const struct comnod *comptr,int flag)
* TODO: find/fix root cause, eliminate argi
*/
argn = *nargs + 1; /* allow room to prepend args */
comargn=(char**)stkalloc(sh.stk,(unsigned)(argn+1)*sizeof(char*));
comargn = stkalloc(sh.stk,(unsigned)(argn+1)*sizeof(char*));
comargm = comargn += argn;
*comargn = NULL;
if(!argp)
Expand Down Expand Up @@ -724,7 +724,7 @@ struct argnod *sh_argprocsub(struct argnod *argp)
int savestates = sh_getstate();
char savejobcontrol = job.jobcontrol;
unsigned int savesubshell = sh.subshell;
ap = (struct argnod*)stkseek(sh.stk,ARGVAL);
ap = stkseek(sh.stk,ARGVAL);
ap->argflag |= ARG_MAKE;
ap->argflag &= ~ARG_RAW;
fd = argp->argflag&ARG_RAW;
Expand Down Expand Up @@ -752,7 +752,7 @@ struct argnod *sh_argprocsub(struct argnod *argp)
sfputr(sh.stk,sh.fifo,0);
#endif /* SHOPT_DEVFD */
sfputr(sh.stk,fmtint(pv[fd],1),0);
ap = (struct argnod*)stkfreeze(sh.stk,0);
ap = stkfreeze(sh.stk,0);
sh.inpipe = sh.outpipe = 0;
/* turn off job control */
sh_offstate(SH_INTERACTIVE);
Expand Down
10 changes: 5 additions & 5 deletions src/cmd/ksh93/sh/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int path_expand(const char *pattern, struct argnod **arghead, int musttrim)
*/
if((ap = (struct argnod*)gp->gl_list) && !ap->argnxt.ap && strcmp(ap->argval,trimmedpat)==0)
{
gp->gl_list = (globlist_t*)stkalloc(sh.stk,ARGVAL+strlen(pattern)+1);
gp->gl_list = stkalloc(sh.stk,ARGVAL+strlen(pattern)+1);
memcpy(gp->gl_list,ap,ARGVAL); /* copy fields *before* argval/gl_path */
strcpy(gp->gl_list->gl_path,pattern);
}
Expand Down Expand Up @@ -149,9 +149,9 @@ static int scantree(Dt_t *tree, const char *pattern, struct argnod **arghead)
continue;
if(strmatch(cp=nv_name(np),pattern))
{
(void)stkseek(sh.stk,ARGVAL);
stkseek(sh.stk,ARGVAL);
sfputr(sh.stk,cp,-1);
ap = (struct argnod*)stkfreeze(sh.stk,1);
ap = stkfreeze(sh.stk,1);
ap->argbegin = NULL;
ap->argchn.ap = *arghead;
ap->argflag = ARG_RAW|ARG_MAKE;
Expand Down Expand Up @@ -431,13 +431,13 @@ int path_generate(struct argnod *todo, struct argnod **arghead, int musttrim)
brace = *cp;
*cp = 0;
sh_sigcheck();
ap = (struct argnod*)stkseek(sh.stk,ARGVAL);
ap = stkseek(sh.stk,ARGVAL);
ap->argflag = ARG_RAW;
ap->argchn.ap = todo;
sfputr(sh.stk,apin->argval,-1);
sfputr(sh.stk,pat,-1);
sfputr(sh.stk,rescan,-1);
todo = ap = (struct argnod*)stkfreeze(sh.stk,1);
todo = ap = stkfreeze(sh.stk,1);
if(brace == '}')
break;
if(!range)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/sh/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ int sh_trap(const char *trap, int mode)
char was_no_trapdontexec = !sh.st.trapdontexec;
char save_chldexitsig = sh.chldexitsig;
int staktop = stktell(sh.stk);
char *savptr = stkfreeze(sh.stk,0);
void *savptr = stkfreeze(sh.stk,0);
struct checkpt buff;
Fcin_t savefc;
fcsave(&savefc);
Expand Down
5 changes: 2 additions & 3 deletions src/cmd/ksh93/sh/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static int rand_shift;
/*
* Exception callback routine for stk(3) and sh_*alloc wrappers.
*/
static noreturn char *nomemory(size_t s)
static noreturn void *nomemory(size_t s)
{
errormsg(SH_DICT, ERROR_SYSTEM|ERROR_PANIC, "out of memory (needed %llu bytes)", (uintmax_t)s);
UNREACHABLE();
Expand Down Expand Up @@ -1310,7 +1310,7 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
sh.lex_context = sh_lexopen(0,1);
sh.radixpoint = '.'; /* pre-locale init */
sh.strbuf = sfstropen();
sh.stk = stkstd;
stkoverflow(sh.stk = stkstd, nomemory);
sfsetbuf(sh.strbuf,NULL,64);
error_info.catalog = e_dict;
#if SHOPT_REGRESS
Expand Down Expand Up @@ -1359,7 +1359,6 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
sh_ioinit();
/* initialize signal handling */
sh_siginit();
stkinstall(NULL,nomemory);
/* set up memory for name-value pairs */
sh.init_context = nv_init();
/* initialize shell type */
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/ksh93/sh/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ int sh_redirect(struct ionod *iop, int flag)
{
if(iof&IOLSEEK)
{
struct argnod *ap = (struct argnod*)stkalloc(sh.stk,ARGVAL+strlen(iop->ioname));
struct argnod *ap = stkalloc(sh.stk,ARGVAL+strlen(iop->ioname));
memset(ap, 0, ARGVAL);
ap->argflag = ARG_MAC;
strcpy(ap->argval,iop->ioname);
Expand All @@ -1202,7 +1202,7 @@ int sh_redirect(struct ionod *iop, int flag)
if((iof&IOPROCSUB) && !(iof&IOLSEEK))
{
/* handle process substitution passed to redirection */
struct argnod *ap = (struct argnod*)stkalloc(sh.stk,ARGVAL+strlen(iop->ioname));
struct argnod *ap = stkalloc(sh.stk,ARGVAL+strlen(iop->ioname));
memset(ap, 0, ARGVAL);
if(iof&IOPUT)
ap->argflag = ARG_RAW;
Expand Down Expand Up @@ -2201,7 +2201,7 @@ static int io_prompt(Sfio_t *iop,int flag)
/* PS2 prompt. Save stack state to avoid corrupting command substitutions
* in case we're executing a PS2.get discipline function at parse time. */
int savestacktop = stktell(sh.stk);
char *savestackptr = stkfreeze(sh.stk,0);
void *savestackptr = stkfreeze(sh.stk,0);
cp = nv_getval(sh_scoped(PS2NOD));
stkset(sh.stk, savestackptr, savestacktop);
break;
Expand Down
13 changes: 7 additions & 6 deletions src/cmd/ksh93/sh/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ static void refvar(Lex_t *lp, int type)
else
{
int n,offset = stktell(sh.stk);
char *savptr,*begin;
void *savptr;
char *begin;
off = offset + (fcseek(0)-(type+1)) - fcfirst();
if(lp->lexd.kiaoff < offset)
{
Expand Down Expand Up @@ -150,7 +151,7 @@ static void lex_advance(Sfio_t *iop, const char *buff, int size, void *context)
size -= (lp->lexd.first-(char*)buff);
buff = lp->lexd.first;
if(!lp->lexd.noarg)
lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
lp->arg = stkseek(sh.stk,ARGVAL);
#if SHOPT_KIA
lp->lexd.kiaoff += ARGVAL;
#endif /* SHOPT_KIA */
Expand Down Expand Up @@ -1252,7 +1253,7 @@ int sh_lex(Lex_t* lp)
state = fcfirst();
n = fcseek(0)-(char*)state;
if(!lp->arg)
lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
lp->arg = stkseek(sh.stk,ARGVAL);
if(n>0)
sfwrite(sh.stk,state,n);
sfputc(sh.stk,0);
Expand Down Expand Up @@ -1286,7 +1287,7 @@ int sh_lex(Lex_t* lp)
{
/* Redirection of the form {varname}>file, etc. */
stkseek(sh.stk,stktell(sh.stk)-1);
lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
lp->arg = stkfreeze(sh.stk,1);
return lp->token=IOVNAME;
}
c = wordflags;
Expand All @@ -1310,7 +1311,7 @@ int sh_lex(Lex_t* lp)
}
if(c==0 || (c&(ARG_MAC|ARG_EXP|ARG_MESSAGE)))
{
lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
lp->arg = stkfreeze(sh.stk,1);
lp->arg->argflag = (c?c:ARG_RAW);
}
else if(mode==ST_NONE)
Expand Down Expand Up @@ -2202,7 +2203,7 @@ static struct argnod *endword(int mode)
stkseek(sh.stk,dp - (unsigned char*)stkptr(sh.stk,0));
if(mode<=0)
{
argp = (struct argnod*)stkfreeze(sh.stk,0);
argp = stkfreeze(sh.stk,0);
argp->argflag = ARG_RAW|ARG_QUOTED;
}
return argp;
Expand Down
7 changes: 4 additions & 3 deletions src/cmd/ksh93/sh/macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1484,7 +1484,7 @@ static int varsub(Mac_t *mp)
if(np && (type==M_BRACE ? !nv_isnull(np) : (type==M_TREE || !c || !ap)))
{
/* Either the parameter is set, or it's a special type of expansion where 'unset' doesn't apply. */
char *savptr;
void *savptr;
c = *((unsigned char*)stkptr(stkp,offset-1));
savptr = stkfreeze(stkp,0);
if(type==M_VNAME || (type==M_SUBNAME && ap))
Expand Down Expand Up @@ -2156,7 +2156,8 @@ static void comsubst(Mac_t *mp,Shnode_t* t, int type)
struct slnod *saveslp = sh.st.staklist;
Mac_t savemac = *mp;
int savtop = stktell(stkp);
char lastc=0, *savptr = stkfreeze(stkp,0);
char lastc = '\0';
void *savptr = stkfreeze(stkp,0);
int was_history = sh_isstate(SH_HISTORY);
int was_verbose = sh_isstate(SH_VERBOSE);
int was_interactive = sh_isstate(SH_INTERACTIVE);
Expand Down Expand Up @@ -2573,7 +2574,7 @@ static void endfield(Mac_t *mp,int split)
Stk_t *stkp = sh.stk;
if(stktell(stkp) > ARGVAL || split)
{
argp = (struct argnod*)stkfreeze(stkp,1);
argp = stkfreeze(stkp,1);
argp->argnxt.cp = 0;
argp->argflag = 0;
mp->atmode = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/sh/name.c
Original file line number Diff line number Diff line change
Expand Up @@ -2181,7 +2181,7 @@ char **sh_envgen(void)
nv_offattr(L_ARGNOD,NV_EXPORT);
namec = nv_scan(sh.var_tree,nullscan,NULL,NV_EXPORT,NV_EXPORT);
namec += sh.nenv;
er = (char**)stkalloc(sh.stk,(namec+4)*sizeof(char*));
er = stkalloc(sh.stk,(namec+4)*sizeof(char*));
data.argnam = (er+=2) + sh.nenv;
if(sh.nenv)
memcpy(er,environ,sh.nenv*sizeof(char*));
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/ksh93/sh/nvtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
Expand Down Expand Up @@ -942,7 +942,7 @@ static char *walk_tree(Namval_t *np, Namval_t *xp, int flags)
Sfio_t *outfile;
Sfoff_t off = 0;
int len, savtop = stktell(sh.stk);
char *savptr = stkfreeze(sh.stk,0);
void *savptr = stkfreeze(sh.stk,0);
struct argnod *ap=0;
struct argnod *arglist=0;
char *name,*cp, **argv;
Expand Down Expand Up @@ -1006,7 +1006,7 @@ static char *walk_tree(Namval_t *np, Namval_t *xp, int flags)
}
stkseek(sh.stk,ARGVAL);
sfputr(sh.stk,cp,-1);
ap = (struct argnod*)stkfreeze(sh.stk,1);
ap = stkfreeze(sh.stk,1);
ap->argflag = ARG_RAW;
ap->argchn.ap = arglist;
n++;
Expand All @@ -1018,7 +1018,7 @@ static char *walk_tree(Namval_t *np, Namval_t *xp, int flags)
sh.var_tree = save_tree;
return NULL;
}
argv = (char**)stkalloc(sh.stk,(n+1)*sizeof(char*));
argv = stkalloc(sh.stk,(n+1)*sizeof(char*));
argv += n;
*argv = 0;
for(; ap; ap=ap->argchn.ap)
Expand Down
Loading

0 comments on commit 6465cfc

Please sign in to comment.