Skip to content

Commit

Permalink
Functions should work for sourced scripts.
Browse files Browse the repository at this point in the history
Next, make a table of functions so they can be called globally. Currently, it isn't possible to call functions from sourced files other than the current.
  • Loading branch information
Krush206 committed Feb 14, 2024
1 parent 24fc5ce commit 13bc485
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 30 deletions.
51 changes: 42 additions & 9 deletions sh.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ int exitset = 0;
static time_t chktim; /* Time mail last checked */
char *progname;
int tcsh;
struct funcargs *fargv = NULL;
struct funccurr fcurr;

/*
* This preserves the input state of the shell. It is used by
Expand Down Expand Up @@ -1725,6 +1725,7 @@ static void
srcunit(int unit, int onlyown, int hflg, Char **av)
{
struct saved_state st;
struct funcargs *fargv;

st.SHIN = -1; /* st_restore checks this */

Expand Down Expand Up @@ -1766,15 +1767,17 @@ srcunit(int unit, int onlyown, int hflg, Char **av)
* then seek for an ending exit on the requested label.
* Function arguments are passed to STRargv.
* STRargv is reset after the function is done. */
if (fargv) {
if (fcurr.ready) {
Char funcexit[] = { 'e', 'x', 'i', 't', 0 },
funcmain[] = { 'm', 'a', 'i', 'n', 0 };
*funcmain = fcurr.ffile ?
strsave(str2short(fcurr.ffile->file)) :
ffile;
struct Strbuf aword = Strbuf_INIT;

Sgoal = fargv->v[0];
Stype = TC_GOTO;
fargv->eof = 0;

if (!fargv->prev)
fcurr.eof = 0;
if (!(fargv = fcurr.fargv)->prev || fcurr.src)
while (1) {
(void) getword(&aword);
Strbuf_terminate(&aword);
Expand All @@ -1799,6 +1802,7 @@ srcunit(int unit, int onlyown, int hflg, Char **av)
}
last = 1;
}
fcurr.src = 0;

break;
}
Expand All @@ -1807,6 +1811,8 @@ srcunit(int unit, int onlyown, int hflg, Char **av)

(void) getword(NULL);
}
if (funcmain != ffile)
xfree(funcmain);

setq(STRargv, &fargv->v[1], &shvhed, VAR_READWRITE);
gotolab(fargv->v[0]);
Expand All @@ -1826,11 +1832,11 @@ srcunit(int unit, int onlyown, int hflg, Char **av)
if (eq(aword.s, funcexit)) {
int last = 1, eof = 0;

fargv->eof = 1;
fcurr.eof = 1;
while (1) {
do {
(void) getword(NULL);
if ((intptr_t) getword(&aword) == (intptr_t) &fargv) {
if (getword(&aword) == (1 << 1)) {
Strbuf_terminate(&aword);
eof = 1;
break;
Expand Down Expand Up @@ -2294,6 +2300,7 @@ dosource(Char **t, struct command *c)
Char *f;
int hflg = 0;
char *file;
struct funcfile **ffile = NULL;

USE(c);
t++;
Expand All @@ -2309,13 +2316,39 @@ dosource(Char **t, struct command *c)
}

f = globone(*t++, G_ERROR);
file = strsave(short2str(f));
fcurr.file = file = strsave(short2str(f));
cleanup_push(file, xfree);
xfree(f);
t = glob_all_or_error(t);
cleanup_push(t, blk_cleanup);
if (fcurr.fargv) {
if (*(ffile = &fcurr.ffile)) {
(*ffile)->next = malloc(sizeof **ffile);
(*ffile)->next->prev = *ffile;
*ffile = (*ffile)->next;
(*ffile)->file = fcurr.file;
} else {
*ffile = malloc(sizeof **ffile);
(*ffile)->prev = NULL;
(*ffile)->file = fcurr.file;
}
}

fcurr.ready = 0;
fcurr.src = 1;
if ((!srcfile(file, 0, hflg, t)) && (!hflg) && (!bequiet))
stderror(ERR_SYSTEM, file, strerror(errno));
if (ffile) {
if ((*ffile)->prev) {
*ffile = (*ffile)->prev;
free((*ffile)->next);
fcurr.file = (*ffile)->file;
} else {
fcurr.file = (*ffile)->file = NULL;
free(*ffile);
*ffile = NULL;
}
}
cleanup_until(file);
}

Expand Down
38 changes: 23 additions & 15 deletions sh.func.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,8 +1096,8 @@ getword(struct Strbuf *wp)
break;

case TC_EXIT:
if (fargv->eof)
return (intptr_t) &fargv;
if (fcurr.eof)
return 1 << 1;
setname(short2str(Sgoal));
stderror(ERR_NAME | ERR_NOTFOUND, "exit");
break;
Expand Down Expand Up @@ -2729,16 +2729,19 @@ getYN(const char *prompt)
void
dofunction(Char **v, struct command *t)
{
char *file;
struct funcargs **fargv;

if (!dolzero)
stderror(ERR_FUNC);

if (fargv) {
fargv->next = malloc(sizeof *fargv);
fargv->next->prev = fargv;
fargv = fargv->next;
if (*(fargv = &fcurr.fargv)) {
(*fargv)->next = malloc(sizeof **fargv);
(*fargv)->next->prev = *fargv;
*fargv = (*fargv)->next;
} else {
fargv = malloc(sizeof *fargv);
fargv->prev = NULL;
*fargv = malloc(sizeof **fargv);
(*fargv)->prev = NULL;
}

{
Expand All @@ -2752,18 +2755,23 @@ dofunction(Char **v, struct command *t)
}

vh[i] = NULL;
fargv->v = vh;
(*fargv)->v = vh;
}
fcurr.ready = 1;

srcfile(short2str(ffile), 0, 0, NULL);
if (!srcfile(file = fcurr.file ? fcurr.file :
strsave(short2str(ffile)), 0, 0, NULL))
stderror(ERR_SYSTEM, file, strerror(errno));
if (file != fcurr.file)
xfree(file);
/* Reset STRargv on function exit. */
setv(STRargv, NULL, VAR_READWRITE);

if (fargv->prev) {
fargv = fargv->prev;
free(fargv->next);
if ((*fargv)->prev) {
*fargv = (*fargv)->prev;
free((*fargv)->next);
} else {
free(fargv);
fargv = NULL;
free(*fargv);
*fargv = NULL;
}
}
22 changes: 16 additions & 6 deletions sh.h
Original file line number Diff line number Diff line change
Expand Up @@ -1308,12 +1308,22 @@ extern int filec;
/* Function variable(s) and function(s). */
extern Char *Sgoal;
extern int Stype;
extern struct funcargs {
Char **v;
int eof;
struct funcargs *prev,
*next;
} *fargv;
extern struct funccurr {
struct funcargs {
Char **v;
struct funcargs *prev,
*next;
} *fargv;
struct funcfile {
char *file;
struct funcfile *prev,
*next;
} *ffile;
char *file;
int eof,
src,
ready;
} fcurr;
extern int getword(struct Strbuf *);
extern int srcfile(const char *, int, int, Char **);

Expand Down

0 comments on commit 13bc485

Please sign in to comment.