bool cp_oddcomm(char *s, wordlist *wl) { FILE *fp; if ((fp = inp_pathopen(s, "r")) != NULL) { char buf[BSIZE_SP]; wordlist *setarg; (void) fclose(fp); (void) sprintf(buf, "argc = %d argv = ( ", wl_length(wl)); while (wl) { (void) strcat(buf, wl->wl_word); (void) strcat(buf, " "); wl = wl->wl_next; } (void) strcat(buf, ")"); setarg = cp_lexer(buf); com_set(setarg); wl_free(setarg); inp_source(s); cp_remvar("argc"); cp_remvar("argv"); return (TRUE); } if (wl && eq(wl->wl_word, "=")) { wordlist *ww = wl_cons(copy(s), wl); com_let(ww); wl_delete_slice(ww, ww->wl_next); return (TRUE); } return (FALSE); }
bool cp_oddcomm(char *s, wordlist *wl) { FILE *fp; char buf[BSIZE_SP]; wordlist ww; if ((fp = inp_pathopen(s, "r"))) { (void) fclose(fp); (void) sprintf(buf, "argc = %d argv = ( ", wl_length(wl)); while (wl) { (void) strcat(buf, wl->wl_word); (void) strcat(buf, " "); wl = wl->wl_next; } (void) strcat(buf, ")"); com_set(cp_lexer(buf)); inp_source(s); cp_remvar("argc"); cp_remvar("argv"); return (TRUE); } else if (wl && eq(wl->wl_word, "=")) { ww.wl_next = wl; wl->wl_prev = &ww; ww.wl_prev = NULL; ww.wl_word = s; com_let(&ww); return (TRUE); } else return (FALSE); }
/* Evaluate a variable. */ wordlist * vareval(char *string) { struct variable *v; wordlist *wl; char buf[BSIZE_SP], *s; char *oldstring = copy(string); char *range = NULL; int i, up, low; cp_wstrip(string); if ((s = strchr(string, '[')) != NULL) { *s = '\0'; range = s + 1; } switch (*string) { case '$': wl = wl_cons(tprintf("%d", getpid()), NULL); tfree(oldstring); return (wl); case '<': (void) fflush(cp_out); if (!fgets(buf, BSIZE_SP, cp_in)) { clearerr(cp_in); (void) strcpy(buf, "EOF"); } for (s = buf; *s && (*s != '\n'); s++) ; *s = '\0'; wl = cp_lexer(buf); /* This is a hack. */ if (!wl->wl_word) wl->wl_word = copy(""); tfree(oldstring); return (wl); case '?': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); wl = wl_cons(copy(v ? "1" : "0"), NULL); tfree(oldstring); return (wl); case '#': string++; for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v) v = cp_enqvar(string); if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } if (v->va_type == CP_LIST) for (v = v->va_vlist, i = 0; v; v = v->va_next) i++; else i = (v->va_type != CP_BOOL); wl = wl_cons(tprintf("%d", i), NULL); tfree(oldstring); return (wl); case '\0': wl = wl_cons(copy("$"), NULL); tfree(oldstring); return (wl); } /* The notation var[stuff] has two meanings... If this is a real * variable, then the [] denotes range, but if this is a strange * (e.g, device parameter) variable, it could be anything... */ for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break; if (!v && isdigit_c(*string)) { for (v = variables; v; v = v->va_next) if (eq(v->va_name, "argv")) break; range = string; } if (!v) { range = NULL; string = oldstring; v = cp_enqvar(string); } if (!v && (s = getenv(string)) != NULL) { wl = wl_cons(copy(s), NULL); tfree(oldstring); return (wl); } if (!v) { fprintf(cp_err, "Error: %s: no such variable.\n", string); tfree(oldstring); return (NULL); } wl = cp_varwl(v); /* Now parse and deal with 'range' ... */ if (range) { /* rather crude fix when range itself is a $expression */ wordlist *r = NULL; if (*range == '$') { char *t = ++range; if (*t == '&') t++; while (isalnum_c(*t)) t++; *t = '\0'; r = vareval(range); if (!r || r->wl_next) { fprintf(cp_err, "Error: %s: illegal index.\n", string); tfree(oldstring); wl_free(r); return NULL; } range = r->wl_word; } for (low = 0; isdigit_c(*range); range++) low = low * 10 + *range - '0'; if ((*range == '-') && isdigit_c(range[1])) for (up = 0, range++; isdigit_c(*range); range++) up = up * 10 + *range - '0'; else if (*range == '-') up = wl_length(wl); else up = low; up--, low--; wl = wl_range(wl, low, up); wl_free(r); } tfree(oldstring); return (wl); }
/* Note that we only do io redirection when we get to here - we also * postpone some other things until now. */ static void docommand(wordlist *wlist) { wordlist *rwlist; if (cp_debug) { printf("docommand "); wl_print(wlist, stdout); putc('\n', stdout); } /* Do all the things that used to be done by cshpar when the line * was read... */ wlist = cp_variablesubst(wlist); pwlist(wlist, "After variable substitution"); wlist = cp_bquote(wlist); pwlist(wlist, "After backquote substitution"); wlist = cp_doglob(wlist); pwlist(wlist, "After globbing"); pwlist_echo(wlist, "Becomes >"); if (!wlist || !wlist->wl_word) /*CDHW need to free wlist in second case? CDHW*/ return; /* Now loop through all of the commands given. */ rwlist = wlist; while (wlist) { char *s; int i; struct comm *command; wordlist *nextc, *ee; nextc = wl_find(cp_csep, wlist); if (nextc == wlist) { /* skip leading `;' */ wlist = wlist->wl_next; continue; } /* Temporarily hide the rest of the command... */ ee = wlist->wl_prev; wl_chop(nextc); wl_chop(wlist); /* And do the redirection. */ cp_ioreset(); for (i = 0; noredirect[i]; i++) if (eq(wlist->wl_word, noredirect[i])) break; if (!noredirect[i]) if ((wlist = cp_redirect(wlist)) == NULL) { cp_ioreset(); return; } /* Get rid of all the 8th bits now... */ cp_striplist(wlist); s = wlist->wl_word; /* Look for the command in the command list. */ for (i = 0; cp_coms[i].co_comname; i++) if (strcasecmp(cp_coms[i].co_comname, s) == 0) break; command = &cp_coms[i]; /* Now give the user-supplied command routine a try... */ if (!command->co_func && cp_oddcomm(s, wlist->wl_next)) goto out; /* If it's not there, try it as a unix command. */ if (!command->co_comname) { if (cp_dounixcom && cp_unixcom(wlist)) goto out; fprintf(cp_err, "%s: no such command available in %s\n", s, cp_program); goto out; /* If it hasn't been implemented */ } else if (!command->co_func) { fprintf(cp_err, "%s: command is not implemented\n", s); goto out; /* If it's there but spiceonly, and this is nutmeg, error. */ } else if (ft_nutmeg && command->co_spiceonly) { fprintf(cp_err, "%s: command available only in spice\n", s); goto out; } /* The command was a valid spice/nutmeg command. */ { int nargs = wl_length(wlist->wl_next); if (nargs < command->co_minargs) { if (command->co_argfn) { command->co_argfn (wlist->wl_next, command); } else { fprintf(cp_err, "%s: too few args.\n", s); } } else if (nargs > command->co_maxargs) { fprintf(cp_err, "%s: too many args.\n", s); } else { command->co_func (wlist->wl_next); } } out: wl_append(ee, wlist); wl_append(wlist, nextc); if (!ee) rwlist = wlist; wlist = nextc; } wl_free(rwlist); /* Do periodic sorts of things... */ cp_periodic(); cp_ioreset(); }