/* * eval by boolean. * return value : value : num * 1 : true (bool) * 0 : false (bool) of error */ static int eval_tree(struct node_t *p) { int lval,rval; if(!p) return 0; /* this should not happen in this function */ switch (p->op) { case O_NUM: return *(int *)p->left; case O_ID: /* not inserted id --> 0 */ return 0; case O_AND: case O_OR: case O_LESS: case O_LESSEQ: case O_EQ: case O_MOREEQ: case O_MORE: lval = eval_tree(p->left); rval = eval_tree(p->right); if(p->op == O_AND) return (lval && rval); if(p->op == O_OR) return (lval || rval); if(p->op == O_LESS) return (lval < rval); if(p->op == O_LESSEQ) return (lval <= rval); if(p->op == O_EQ) return (lval == rval); if(p->op == O_MORE) return (lval >= rval); if(p->op == O_MOREEQ) return (lval > rval); default: return 0; } }
/* evaluate case conditional construct (3.9.4.3) * ----------------------------------------------------------------------- */ int eval_case(struct eval *e, struct ncase *ncase) { union node *node; union node *pat; int ret = 0; stralloc word; stralloc pattern; stralloc_init(&word); stralloc_init(&pattern); if(ncase->word) expand_catsa(ncase->word, &word, X_NOSPLIT); stralloc_nul(&word); for(node = ncase->list; node; node = node->list.next) { for(pat = node->ncasenode.pats; pat; pat = pat->list.next) { expand_catsa(pat, &pattern, X_NOSPLIT); stralloc_nul(&pattern); if(shell_fnmatch(pattern.s, pattern.len, word.s, word.len, SH_FNM_PERIOD) == 0) { ret = eval_tree(e, node->ncasenode.cmds, E_LIST); goto end; } stralloc_zero(&pattern); } } end: stralloc_free(&pattern); stralloc_free(&word); return ret; }
void do_pred_testing(void) { int sts; config_vars vars; FILE *conf = NULL; conf = open_config(); read_config(conf); (void)fclose(conf); dump_tree(stdout); for (;;) { sts = read_test_values(stdin, &vars); if (sts == EOF) break; if (sts == 0) { (void)fprintf(stderr, "Bad input line\n"); continue; } if (eval_tree(&vars)) { (void)fprintf(stdout, "true\n"); } else { (void)fprintf(stdout, "false\n"); } } }
/* * judge if bw is OK in 'rulestr' * return value: 0 ... no, it's not OK. * non 0 ... yes, it is. use this rule. */ int asmrule_match(char *rulestr,int bw) { int ret = 0; struct node_t *p; struct c_desc *cd; if(rulestr[0] != '#') { /* asmrule always start with #*/ return 1; /* if not, it's no description rule --> always match */ } cd = new_c_desc(rulestr + 1); p = cond_expr(cd); /*tree_debug(p); debugging*/ insert_id_value(p,"OldPNMPlayer",0); /* we don't care about old player */ insert_id_value(p,"Bandwidth",bw); ret = eval_tree(p); free_node_t(p); free_c_desc(cd); return ret; }
/* evaluate while/until-loop (3.9.4.5 - 3.9.4.6) * ----------------------------------------------------------------------- */ int eval_loop(struct eval *e, struct nloop *nloop) { struct eval en; int retcode = (nloop->id == N_WHILE) ? 0 : 1; int ret = 0; eval_push(&en, 0); en.jump = 1; if(setjmp(en.jmpbuf) == 1) return ret; while((eval_tree(e, nloop->test, E_LIST) == retcode)) /* evaluate loop body */ eval_tree(e, nloop->cmds, E_LIST); return eval_pop(&en); }
/* evaluate if-conditional (3.9.4.4) * ----------------------------------------------------------------------- */ int eval_if(struct eval *e, struct nif *nif) { int ret; union node *branch; elif: ret = eval_tree(e, nif->test, E_LIST); /* do not recurse for elifs */ if(ret && nif->cmd1) { if(nif->cmd1->list.id == N_IF) { nif = &nif->cmd1->nif; goto elif; } } /* take the branch */ branch = ret ? nif->cmd1 : nif->cmd0; if(branch) return eval_tree(e, branch, E_LIST); return 0; }
/* main loop, parse lines into trees and execute them * ----------------------------------------------------------------------- */ void sh_loop(void) { struct parser p; union node *list; stralloc cmd; /* if we're in interactive mode some additional stuff is to be initialized */ if(source->mode & SOURCE_IACTIVE) history_load(); stralloc_init(&cmd); parse_init(&p, P_DEFAULT); while(!(parse_gettok(&p, P_DEFAULT) & T_EOF)) { p.pushback++; parse_lineno = source->line; var_setvint("LINENO", parse_lineno, V_DEFAULT); /* launch the parser to get a complete command */ if((list = parse_list(&p))) { struct eval e; if(source->mode & SOURCE_IACTIVE) { tree_printlist(list, &cmd, NULL); stralloc_catc(&cmd, '\n'); stralloc_nul(&cmd); history_set(cmd.s); cmd.s = NULL; history_advance(); } #ifdef DEBUG /* debug_list(list, 0); buffer_putnlflush(fd_err->w);*/ #endif /* DEBUG */ eval_push(&e, E_JCTL); eval_tree(&e, list, E_ROOT|E_LIST); sh->exitcode = eval_pop(&e); stralloc_zero(&cmd); tree_free(list); } else if(!(p.tok & (T_NL | T_SEMI | T_BGND))) { /* we have a parse error */ if(p.tok != T_EOF) parse_error(&p, 0); /* exit if not interactive */ if(!(source->mode & SOURCE_IACTIVE)) sh_exit(1); /* ..otherwise discard the input buffer */ source_flush(); p.pushback = 0; } if(p.tok & (T_NL|T_SEMI|T_BGND)) p.pushback = 0; /* reset prompt */ prompt_number = 0; } }
/* evaluate a pipeline (3.9.2) * ----------------------------------------------------------------------- */ int eval_pipeline(struct eval *e, struct npipe *npipe) { struct job *job; union node *node; struct fdstack st; unsigned int n; int pid = 0; int prevfd = -1; int status = -1; /* job = (e->flags & E_JCTL) ? job_new(npipe->ncmd) : NULL;*/ job = job_new(npipe->ncmd); if(job == NULL) { buffer_puts(fd_err->w, "no job control"); buffer_putnlflush(fd_err->w); } for(node = npipe->cmds; node; node = node->list.next) { fdstack_push(&st); /* if there was a previous command we read input from pipe */ if(prevfd >= 0) { struct fd *in; fd_alloca(in); fd_push(in, STDIN_FILENO, FD_READ|FD_PIPE); fd_setfd(in, prevfd); } /* if it isn't the last command we have to create a pipe to pass output to the next command */ if(node->list.next) { struct fd *out; fd_alloca(out); fd_push(out, STDOUT_FILENO, FD_WRITE|FD_PIPE); prevfd = fd_pipe(out); if(prevfd == -1) { close(prevfd); sh_error("pipe creation failed"); } } if((n = fdstack_npipes(FD_HERE|FD_SUBST))) fdstack_pipe(n, fdstack_alloc(n)); pid = job_fork(job, node, npipe->bgnd); if(!pid) { /* no job control for commands inside pipe */ /* e->mode &= E_JCTL;*/ /* exit after evaluating this subtree */ exit(eval_tree(e, node, E_EXIT)); } fdstack_pop(&st); fdstack_data(); } if(!npipe->bgnd) { job_wait(job, 0, &status, 0); } /* if(job) shell_free(job);*/ return WEXITSTATUS(status); }