struct cmd* parseexec(char **ps, char *es) { char *q, *eq; int tok, argc; struct execcmd *cmd; struct cmd *ret; ret = execcmd(); cmd = (struct execcmd*)ret; argc = 0; ret = parseredirs(ret, ps, es); while(!peek(ps, es, "|")){ if((tok=gettoken(ps, es, &q, &eq)) == 0) break; if(tok != 'a') { fprintf(stderr, "syntax error\n"); exit(-1); } cmd->argv[argc] = mkcopy(q, eq); argc++; if(argc >= MAXARGS) { fprintf(stderr, "too many args\n"); exit(-1); } ret = parseredirs(ret, ps, es); } cmd->argv[argc] = 0; return ret; }
struct cmd* parseredirs(struct cmd *cmd, char **ps, char *es) { int tok; char *q, *eq; while(peek(ps, es, "<>")){ tok = gettoken(ps, es, 0, 0); if(gettoken(ps, es, &q, &eq) != 'a') { fprintf(stderr, "missing file for redirection\n"); exit(-1); } switch(tok){ case '<': cmd = redircmd(cmd, mkcopy(q, eq), '<'); break; case '>': cmd = redircmd(cmd, mkcopy(q, eq), '>'); break; } } return cmd; }
/* 按字面意思理解应该是分析重定向行为的函数 */ struct cmd* parseredirs(struct cmd *cmd, char **ps, char *es) { int tok; char *q, *eq; while(peek(ps, es, "<>")){ //去掉前导空白符,并且判断该字符串的首字符是否是<>中的一种 tok = gettoken(ps, es, 0, 0); //如果存在 <> 符号,那么定位这个 <> 符号左面的那个指令 如 $, ps if(gettoken(ps, es, &q, &eq) != 'a') { fprintf(stderr, "missing file for redirection\n"); exit(-1); } switch(tok){ case '<': cmd = redircmd(cmd, mkcopy(q, eq), '<'); break; case '>': cmd = redircmd(cmd, mkcopy(q, eq), '>'); break; } } return cmd; }