/* * Csh - a shell by PJAC * inp.c input routines */ #include "csh.h" in_1char() { if(Cur_ins->i_nleft <= 0){ if(Cur_ins->i_fblk){ puterr("Csh err: End of loop not detected.\n"); longjmp(env_main, INTERUPT); } Cur_ins->i_nleft = read(Cur_ins->i_fd, Cur_ins->i_buf, MAXINLINE); if(Cur_ins->i_nleft <= 0) return(EOF); Cur_ins->i_ptr = Cur_ins->i_buf; } Cur_ins->i_nleft--; return(*(Cur_ins->i_ptr++) & 0177); } readin() { int c; char *p; int special = FALSE; int mchar = '\0'; int mmask = 0; int fchar = TRUE; if(in_len > MAXINLINE){ in_len = MAXINLINE; free(in_buf); in_buf = mmalloc(MAXINLINE+1); } for(in_bufp = in_buf; (c = in_1char()) != EOF;){ switch(c){ case '\r': continue; case '\\': fchar = FALSE; if(special || mchar != '\0') goto dflt; special = TRUE; continue; case '\n': fchar = FALSE; if(special == TRUE){ special = FALSE; add_char(' ' | mmask); if(Prompt[1]) put_prompt(Prompt[1]); continue; } if(mchar != '\0'){ add_char(c | mmask); if(Prompt[1]) put_prompt(Prompt[1]); continue; } *in_bufp = '\0'; return(OK); case '"': case '\'': fchar = FALSE; if(special) goto dflt; if(mchar == '\0'){ add_char(c); mchar = c; mmask = 0200; continue; } if(mchar != c){ add_char(c | mmask); continue; } mchar = 0; mmask = 0; add_char(c); continue; case '!': fchar = FALSE; if(special || mchar == '\'') goto dflt; if(get_hist(mmask) == EOF) return(EOF); continue; case '$': fchar = FALSE; if(special || mchar == '\'') goto dflt; if(get_svar(mmask) == EOF) return(EOF); continue; default: if(fchar){ if(c == '^'){ fchar = FALSE; if(get_bhist(mmask) == EOF) return(EOF); continue; } else if(index(IFS, c) == 0) fchar = FALSE; } dflt:; if(special){ add_char(c | 0200); special = FALSE; } else add_char(c | mmask); continue; } } return(EOF); } add_char(c) { char *p; if(in_bufp > in_buf + in_len - 1){ *in_bufp = 0; p = mmalloc(in_len + MAXINLINE); strcpy(p, in_buf); in_bufp = &p[in_bufp - in_buf]; in_len += MAXINLINE; in_buf = p; } *in_bufp++ = c; } /* * get a shell variable, copes with $x or ${var} syntax */ get_svar(mmask) { char *p, **xp; int c; struct lvars *lp; int fmember = -1; int lmember = -1; char *q, *s; int seenb = 0; int fchar = 0; int i; char lbuf[128]; struct lvars *xlp = 0; p = lbuf; for(p = lbuf ; (c = in_1char()) != EOF; *p++ = c){ if(c == '{') if(p == lbuf) continue; if(index(IFS, c)) break; if(p > lbuf && *lbuf == '{' && c != '}') continue; if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue; if(p == lbuf && (c == '#' || c == '?')) continue; if(c == '['){ if(seenb) break; seenb = 1; continue; } if(c == ']'){ if(!seenb) break; if(*lbuf == '{') continue; *p++ = c; c = in_1char(); break; } if(c == '-' && seenb) continue; if(c == '*' || (c >= '0' && c<= '9')){ if(p == lbuf) continue; if(p == lbuf + 1){ if(*lbuf == '{') continue; if(*lbuf == '?' && c == '0') continue; } if(seenb) continue; } break; } *p = 0; p = lbuf; if(*lbuf == '{'){ if(c != '}'){ /* should be a syntax error */ Cur_ins->i_nleft++; /* push back last char */ Cur_ins->i_ptr--; return(ERR); } p++; } if(*p == '\0'){ if(c == EOF) return(EOF); if(index(IFS, c)) add_char('$' | mmask); if(*lbuf != '{'){ Cur_ins->i_nleft++; /* push back last char */ Cur_ins->i_ptr--; } return(OK); } if(c == EOF) return(EOF); if(*lbuf != '{'){ Cur_ins->i_nleft++; /* push back last char */ Cur_ins->i_ptr--; } q = index(p, '['); s = index(p, ']'); if(s || q){ if(!q || !s || s < q || *(s+1)) /* error */ return(ERR); *q++ = '\0'; *s = '\0'; if(*q == '*'){ fmember = 1; lmember = 10000; /* a big number */ q++; } else { if(*q == '-') fmember = 1; else { fmember = 0; while(*q >= '0' && *q <= '9') fmember = fmember * 10 + (*q++ - '0'); } lmember = fmember; if(*q == '-'){ if(*++q == '\0') lmember = 10000; else { lmember = 0; while(*q >= '0' && *q <= '9') lmember = lmember * 10 + (*q++ - '0'); } } } if(*q) /* got a syntax error */ return(ERR); if(lmember < fmember) return(OK); } if(*p == '*'){ if(fmember != -1) return(ERR); p = "argv"; fmember = 1; lmember = 10000; } else if(*p == '0') return(ERR); /* don't know name prog was called by */ else if(*p >= '1' && *p <= '9'){ if(fmember != -1) return(ERR); lmember = fmember = atoi(p); p = "argv"; } else if(*p == '#' || *p == '?'){ if(fmember != -1) return(ERR); if(p[1] == '0' && *p == '?'){ add_char('0' | mmask); /* we never know the name we */ return(OK); /* are called with */ } fchar = *p++; } if(lmember < 0 && fmember < 0){ fmember = 1; lmember = 10000; } /* * now find the variable */ for(lp = Lvars ; lp ; lp = lp->L_next) if(strcmp(lp->L_name, p) == 0) break; if(lp == 0){ /* maybe the variable is in the environment */ i = strlen(p); for(xp = Real_Environ ; *xp ; xp++) if(strncmp(*xp, p, i) == 0 && (*xp)[i] == '=') break; if(*xp){ /* yep - it's there - build an lvars struct to hold it*/ xlp = (struct lvars *)mmalloc(sizeof(struct lvars)); xlp->L_aval = (char **)mmalloc(sizeof(char *) * 2); xlp->L_aval[0] = (*xp) + i + 1; xlp->L_aval[1] = 0; lp = xlp; } } if(lp){ if(fchar){ if(fchar == '#'){ i = 0; if(xp = lp->L_aval) while(*xp++) i++; p = my_Itoa(i); while(*p) add_char(*p++ | mmask); } else add_char('1' | mmask); /* it exists */ if(xlp != 0){ free((char *)xlp->L_aval); free((char *)xlp); } return(OK); } lmember--; fmember--; if(xp = lp->L_aval){ for( ; *xp && fmember > 0 ; xp++, fmember--) lmember--; while((p = *xp++) && lmember-- >= 0){ while(*p) add_char(*p++ | mmask); if(*xp && lmember >= 0) add_char(' ' | mmask); } } if(xlp != 0){ free((char *)xlp->L_aval); free((char *)xlp); } } else if(fchar){ /* string don't exist say so */ add_char('0' | mmask); } else if(strcmp(p, "status") == 0){ p = my_Itoa(status); while(*p) add_char(*p++ | mmask); } return(OK); }