Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* This file contains the code for parser used to parse the input
- * given to shell program. You shouldn't need to modify this
- * file */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "parse.h"
- #define PIPE ('|')
- #define BG ('&')
- #define RIN ('<')
- #define RUT ('>')
- #define ispipe(c) ((c) == PIPE)
- #define isbg(c) ((c) == BG)
- #define isrin(c) ((c) == RIN)
- #define isrut(c) ((c) == RUT)
- #define isspec(c) (ispipe(c) || isbg(c) || isrin(c) || isrut(c))
- static Pgm cmdbuf[20], *cmds;
- static char cbuf[256], *cp;
- static char *pbuf[50], **pp;
- /*
- * A quick hack to parse a commandline
- */
- int
- parse (char *buf, Command *c)
- {
- int n;
- Pgm *cmd0;
- char *t = buf;
- char *tok;
- init();
- c->rstdin = NULL;
- c->rstdout = NULL;
- c->rstderr = NULL;
- c->bakground = 0; /* false */
- c->pgm = NULL;
- newcmd:
- if ((n = acmd(t, &cmd0)) <= 0) {
- return -1;
- }
- t += n;
- cmd0->next = c->pgm;
- c->pgm = cmd0;
- newtoken:
- n = nexttoken(t, &tok);
- if (n == 0) {
- return 1;
- }
- t += n;
- switch(*tok) {
- case PIPE:
- goto newcmd;
- break;
- case BG:
- n = nexttoken(t, &tok);
- if (n == 0) {
- c->bakground = 1;
- return 1;
- }
- else {
- fprintf(stderr, "illegal bakgrounding\n");
- return -1;
- }
- break;
- case RIN:
- if (c->rstdin != NULL) {
- fprintf(stderr, "duplicate redirection of stdin\n");
- return -1;
- }
- if ((n = nexttoken(t, &(c->rstdin))) < 0) {
- return -1;
- }
- if (!isidentifier(c->rstdin)) {
- fprintf(stderr, "Illegal filename: \"%s\"\n", c->rstdin);
- return -1;
- }
- t += n;
- goto newtoken;
- break;
- case RUT:
- if (c->rstdout != NULL) {
- fprintf(stderr, "duplicate redirection of stdout\n");
- return -1;
- }
- if ((n = nexttoken(t, &(c->rstdout))) < 0) {
- return -1;
- }
- if (!isidentifier(c->rstdout)) {
- fprintf(stderr, "Illegal filename: \"%s\"\n", c->rstdout);
- return -1;
- }
- t += n;
- goto newtoken;
- break;
- default:
- return -1;
- }
- goto newcmd;
- }
- void init( void )
- {
- int i;
- for (i=0;i<19;i++) {
- cmdbuf[i].next = &cmdbuf[i+1];
- }
- cmdbuf[19].next = NULL;
- cmds = cmdbuf;
- cp = cbuf;
- pp = pbuf;
- }
- int
- nexttoken( char *s, char **tok)
- {
- char *s0 = s;
- char c;
- *tok = cp;
- while (isspace(c = *s++) && c);
- if (c == '\0') {
- return 0;
- }
- if (isspec(c)) {
- *cp++ = c;
- *cp++ = '\0';
- }
- else {
- *cp++ = c;
- do {
- c = *cp++ = *s++;
- } while (!isspace(c) && !isspec(c) && (c != '\0'));
- --s;
- --cp;
- *cp++ = '\0';
- }
- return s - s0;
- }
- int
- acmd (char *s, Pgm **cmd)
- {
- char *tok;
- int n, cnt = 0;
- Pgm *cmd0 = cmds;
- cmds = cmds->next;
- cmd0->next = NULL;
- cmd0->pgmlist = pp;
- next:
- n = nexttoken(s, &tok);
- if (n == 0 || isspec(*tok)) {
- *cmd = cmd0;
- *pp++ = NULL;
- return cnt;
- }
- else {
- *pp++ = tok;
- cnt += n;
- s += n;
- goto next;
- }
- }
- #define IDCHARS "_-.,/~+"
- int
- isidentifier (char *s)
- {
- while (*s) {
- char *p = strrchr (IDCHARS, *s);
- if (! isalnum(*s++) && (p == NULL))
- return 0;
- }
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement