summaryrefslogtreecommitdiff
path: root/shell/msh_function.patch
diff options
context:
space:
mode:
Diffstat (limited to 'shell/msh_function.patch')
-rw-r--r--shell/msh_function.patch350
1 files changed, 0 insertions, 350 deletions
diff --git a/shell/msh_function.patch b/shell/msh_function.patch
deleted file mode 100644
index 270b9ee..0000000
--- a/shell/msh_function.patch
+++ /dev/null
@@ -1,350 +0,0 @@
-This is a "function" patch for msh which is in use by some busybox
-users. Unfortunately it is far too buggy to be applied, but maybe
-it's a useful starting point for future work.
-
-Function-related code is delimited by comments of the form
- //funccode:start
- ...
- //funccode:end
-for ease of grepping
-
-An example of buggy behavior:
-
-#f() {
-# echo foo
-# echo test`echo bar >&2`
-# echo END f
-#}
-
-function g {
-# echo 2 foo
-# echo 2 test`echo 2 bar >&2`
-# f
- echo END g
-# echo "1:'$1' 2:'$2'"
-}
-
-# Even this first block fails - it does not even call functions!
-# (replacing "echo END g" above with "echo END" makes it run ok)
-echo DRY RUN
- echo 2 foo
- echo 2 test`echo 2 bar >&2`
- echo END g
- echo "1:'$1' 2:'$2'"
- echo foo
- echo test`echo bar >&2`
- echo END f
-echo END DRY RUN
-
-exit
-
-# This would fail too
-g "$1-one" "two$2"
-echo DONE
-
-
-
-diff -d -urpN busybox.7/shell/msh.c busybox.8/shell/msh.c
---- busybox.7/shell/msh.c 2008-06-09 09:34:45.000000000 +0200
-+++ busybox.8/shell/msh.c 2008-06-09 09:38:17.000000000 +0200
-@@ -89,6 +89,14 @@ static char *itoa(int n)
-
- //#define MSHDEBUG 4
-
-+/* Used only in "function" support code */
-+#ifdef KSDBG //funccode:start
-+ #define KSDBG_PRINT_FUNCNAME fprintf(stderr, "in %s\n", __FUNCTION__)
-+#else
-+ #define KSDBG_PRINT_FUNCNAME ((void)0)
-+#endif
-+//funccode:end
-+
- #ifdef MSHDEBUG
- static int mshdbg = MSHDEBUG;
-
-@@ -220,6 +228,9 @@ struct op {
- #define TASYNC 16 /* c & */
- /* Added to support "." file expansion */
- #define TDOT 17
-+#define TFUNC 18 //funccode:start
-+#define TRETURN 19
-+ //funccode:end
-
- /* Strings for names to make debug easier */
- #ifdef MSHDEBUG
-@@ -319,6 +330,27 @@ struct region {
- int area;
- };
-
-+static int func_finished; //funccode:start
-+struct func {
-+ char* name;
-+ int begin_addr; /* pos in buffer of function */
-+ int end_addr;
-+};
-+#define MAX_FUNCS 100
-+
-+static struct func funcs[MAX_FUNCS];
-+
-+/* the max DEPTH of function call */
-+#define MAX_DEPTH 100
-+static struct _frame_s {
-+ int argc;
-+ char **argv;
-+ int saved_return_addr;
-+} frame[MAX_DEPTH];
-+
-+static void register_func(int begin, int end);
-+static struct func* find_func(char* name);
-+static void exec_func(struct func* f); //funccode:end
-
- /* -------- grammar stuff -------- */
- typedef union {
-@@ -347,6 +379,8 @@ typedef union {
- #define IN 272
- /* Added for "." file expansion */
- #define DOT 273
-+#define FUNC 274 //funccode:start
-+#define RETURN 275 //funccode:end
-
- #define YYERRCODE 300
-
-@@ -1722,6 +1756,40 @@ static struct op *simple(void)
- (void) synio(0);
- break;
-
-+ case FUNC: { //funccode:start
-+ int stop_flag;
-+ int number_brace;
-+ int func_begin;
-+ int func_end;
-+ int c;
-+ while ((c = my_getc(0)) == ' ' || c == '\t'|| c == '\n') /* skip whitespace */
-+ continue;
-+ stop_flag = 1;
-+ number_brace = 0;
-+ func_begin = global_env.iobase->argp->afpos;
-+ while (stop_flag) {
-+ if (c == '{')
-+ number_brace++;
-+ if (c == '}')
-+ number_brace--;
-+ if (!number_brace) /* if we reach the brace of most outsite */
-+ stop_flag = 0;
-+ c = my_getc(0);
-+ }
-+ unget(c);
-+ unget(c);
-+ func_end = global_env.iobase->argp->afpos;
-+ register_func(func_begin, func_end);
-+ peeksym = 0;
-+ t = NULL;
-+ return t;
-+ }
-+ case RETURN:
-+ func_finished = 1;
-+ peeksym = 0;
-+ t = NULL;
-+ return t; //funccode:end
-+
- case WORD:
- if (t == NULL) {
- t = newtp();
-@@ -2265,6 +2333,13 @@ static int yylex(int cf)
- case ')':
- startl = 1;
- return c;
-+ case '{': //funccode:start
-+ c = collect(c, '}');
-+ if (c != '\0')
-+ return c;
-+ break;
-+ case '}':
-+ return RETURN; //funccode:end
- }
-
- unget(c);
-@@ -2293,9 +2368,172 @@ static int yylex(int cf)
- }
-
- yylval.cp = strsave(line, areanum);
-+ /* To identify a subroutine */ //funccode:start
-+ c = my_getc(0);
-+ if (c && any(c, "(")) {
-+ c = my_getc(0);
-+ if (c && any(c, ")"))
-+ return FUNC;
-+ zzerr();
-+ } else
-+ unget(c);
-+ /* read the first char */
-+ /* To identify a function */
-+ if (strcmp(yylval.cp, "function") == 0) {
-+ int ret = yylex(0);
-+ /* read the function name after "function" */
-+ if (ret == WORD)
-+ return (FUNC);
-+ zzerr();
-+ }
-+ {
-+ struct func* f = find_func(yylval.cp);
-+ if (f != NULL) {
-+ exec_func(f);
-+ return RETURN;
-+ }
-+ }
-+ if (yylval.cp != NULL && strcmp(yylval.cp, "return") == 0) {
-+ return RETURN;
-+ } //funccode:end
- return WORD;
- }
-
-+static void register_func(int begin, int end) //funccode:start
-+{
-+ struct func *p;
-+ int i;
-+ for (i = 0; i < MAX_FUNCS; i++) {
-+ if (funcs[i].name == NULL) {
-+ p = &funcs[i];
-+ break;
-+ }
-+ }
-+ if (i == MAX_FUNCS) {
-+ fprintf(stderr, "Too much functions beyond limit\n");
-+ leave();
-+ }
-+ p->name = xstrdup(yylval.cp);
-+ //fprintf(stderr, "register function,%d,%d,%s\n", begin, end, p->name);
-+ KSDBG_PRINT_FUNCNAME;
-+ /* io stream */
-+ p->begin_addr = begin;
-+ p->end_addr = end;
-+}
-+
-+static struct func* find_func(char* name)
-+{
-+ int i;
-+ for (i = 0; i < MAX_FUNCS; i++) {
-+ if (funcs[i].name == NULL)
-+ continue;
-+ if (!strcmp(funcs[i].name, name))
-+ return &funcs[i];
-+ }
-+ KSDBG_PRINT_FUNCNAME;
-+ //fprintf(stderr, "not found the function %s\n", name);
-+ return NULL;
-+ //zzerr();
-+}
-+
-+/* Begin to execute the function */
-+static int cur_frame = 0;
-+
-+static void exec_func(struct func* f)
-+{
-+ int c;
-+ int temp_argc;
-+ char** temp_argv;
-+ struct iobuf *bp;
-+
-+ /* create a new frame, save the argument and return address to this frame */
-+ frame[cur_frame].argc = dolc;
-+ frame[cur_frame].argv = dolv;
-+
-+ cur_frame++;
-+ /* do some argument parse and set arguments */
-+ temp_argv = xmalloc(sizeof(char *));
-+ temp_argv[0] = xstrdup(f->name);
-+ temp_argc = 0;
-+ global_env.iop->argp->afpos--;
-+ global_env.iop->argp->afbuf->bufp--;
-+// unget(c);
-+ while (((c = yylex(0)) != '\n') && (yylval.cp != NULL)) {
-+ temp_argc++;
-+ temp_argv = xrealloc(temp_argv, sizeof(char *) * (temp_argc+1));
-+ /* parse $ var if passed argument is a variable */
-+ if (yylval.cp[0] == '$') {
-+ struct var *arg = lookup(&yylval.cp[1]);
-+ temp_argv[temp_argc] = xstrdup(arg->value);
-+ //fprintf(stderr, "arg->value=%s\n", arg->value);
-+ } else {
-+ temp_argv[temp_argc] = xstrdup(yylval.cp);
-+ //fprintf(stderr, "ARG:%s\n", yylval.cp);
-+ }
-+ }
-+ /*
-+ global_env.iop->argp->afpos--;
-+ global_env.iop->argp->afbuf->bufp--;
-+ */
-+ dolc = temp_argc;
-+ dolv = temp_argv;
-+ //unget(c);
-+ //while ((c = my_getc(0)) == ' ' || c == '\t') /* Skip whitespace */
-+ // continue;
-+ //unget(c);
-+ frame[cur_frame].saved_return_addr = global_env.iop->argp->afpos;
-+
-+ /* get function begin address and execute this function */
-+
-+ bp = global_env.iop->argp->afbuf;
-+ bp->bufp = &(bp->buf[f->begin_addr]);
-+ global_env.iop->argp->afpos = f->begin_addr;
-+
-+ /* func_finished=0 means we are in a function and func_finished=1 means we are executing a function */
-+ func_finished = 0;
-+
-+ //fprintf(stderr, "exec function %s\n", f->name);
-+ KSDBG_PRINT_FUNCNAME;
-+ for (;;) {
-+ //fprintf(stderr, "afpos=%d,%s\n", global_env.iop->argp->afpos, yylval.cp);
-+ if (global_env.iop->argp->afpos == f->end_addr)
-+ break;
-+ onecommand();
-+ /* we return from a function, when func_finished = 1 */
-+ if (func_finished)
-+ break;
-+ }
-+
-+ {
-+ //fprintf(stderr, "%s is finished @%d!\n", f->name, global_env.iop->argp->afpos);
-+ int ret = frame[cur_frame].saved_return_addr;
-+ /* workaround code for \n */
-+ if (dolc)
-+ ret--;
-+ /* get return address from current frame and jump to */
-+ global_env.iop->argp->afpos = ret;
-+ global_env.iop->argp->afbuf->bufp = &(global_env.iop->argp->afbuf->buf[ret]);
-+ }
-+ /*
-+ fprintf(stderr, "******** after execution ********************\n");
-+ fprintf(stderr, " %s \n############# %d\n", global_env.iop->argp->afbuf->bufp, ret);
-+ fprintf(stderr, "*******************************\n");
-+ */
-+ /* we return to previous frame */
-+ cur_frame--;
-+ /* free some space occupied by argument */
-+ while (dolc--)
-+ free(dolv[dolc]);
-+ free(dolv);
-+
-+ /* recover argument for last function */
-+ dolv = frame[cur_frame].argv;
-+ dolc = frame[cur_frame].argc;
-+ /* If we are not in the outest frame, we should set
-+ * func_finished to 0 that means we still in some function */
-+ if (cur_frame != 0)
-+ func_finished = 0;
-+} //funccode:end
-
- static int collect(int c, int c1)
- {
-@@ -2601,6 +2839,10 @@ static int execute(struct op *t, int *pi
- execute(t->right->right, pin, pout, /* no_fork: */ 0);
- }
- break;
-+ case TFUNC: //funccode:start
-+ break;
-+ case TRETURN:
-+ break; //funccode:end
-
- case TCASE:
- cp = evalstr(t->str, DOSUB | DOTRIM);