ast_comparator/test/student_data/handout/shlab-handout/cases/reference_11_tsh.c
/* 
 * parseline - Parse the command line and build the argv array.
 * 
 * Parameters:
 *   cmdline:  The command line, in the form:
 *
 *                command [arguments...] [< infile] [> oufile] [&]
 *
 *   tok:      Pointer to a cmdline_tokens structure. The elements of this
 *             structure will be populated with the parsed tokens. Characters 
 *             enclosed in single or double quotes are treated as a single
 *             argument. 
 * Returns:
 *   1:        if the user has requested a BG job
 *   0:        if the user has requested a FG job  
 *  -1:        if cmdline is incorrectly formatted
 * 
 * Note:       The string elements of tok (e.g., argv[], infile, outfile) 
 *             are statically allocated inside parseline() and will be 
 *             overwritten the next time this function is invoked.
 */
Parse the command line and build the argv array.

The command line, in the form.

command [arguments...] [< infile] [> oufile] [&]

Pointer to a cmdline_tokens structure. The elements of this
structure will be populated with the parsed tokens. Characters
enclosed in single or double quotes are treated as a single
argument.
Returns:
1:        if the user has requested a BG job
0:        if the user has requested a FG job
-1:        if cmdline is incorrectly formatted

The string elements of tok
are statically allocated inside parseline() and will be
overwritten the next time this function is invoked.
Parse the command line and build the argv array . The command line in the form . command [ arguments ... ] [ < infile ] [ > oufile ] [ & ] Pointer to a cmdline_tokens structure . The elements of this structure will be populated with the parsed tokens . Characters enclosed in single or double quotes are treated as a single argument . Returns : 1 : if the user has requested a BG job 0 : if the user has requested a FG job - 1 : if cmdline is incorrectly formatted The string elements of tok are statically allocated inside parseline () and will be overwritten the next time this function is invoked .
int 
parseline(const char *cmdline, struct cmdline_tokens *tok) 
{
    static char array[MAXLINE];          
    const char delims[10] = " \t\r\n";   
    char *buf = array;                   
    char *next;                          
    char *endbuf;                        
    int is_bg;                           
    int parsing_state;                   
    if (cmdline == NULL) {
        (void) fprintf(stderr, "Error: command line is NULL\n");
        return -1;
    }
    (void) strncpy(buf, cmdline, MAXLINE);
    endbuf = buf + strlen(buf);
    tok->infile = NULL;
    tok->outfile = NULL;
    parsing_state = ST_NORMAL;
    tok->argc = 0;
    while (buf < endbuf) {
        buf += strspn (buf, delims);
        if (buf >= endbuf) break;
        if (*buf == '<') {
            if (tok->infile) {
                (void) fprintf(stderr, "Error: Ambiguous I/O redirection\n");
                return -1;
            }
            parsing_state |= ST_INFILE;
            buf++;
            continue;
        }
        if (*buf == '>') {
            if (tok->outfile) {
                (void) fprintf(stderr, "Error: Ambiguous I/O redirection\n");
                return -1;
            }
            parsing_state |= ST_OUTFILE;
            buf ++;
            continue;
        }
        if (*buf == '\'' || *buf == '\"') {
            buf++;
            next = strchr (buf, *(buf-1));
        } else {
            next = buf + strcspn (buf, delims);
        }
        if (next == NULL) {
            (void) fprintf (stderr, "Error: unmatched %c.\n", *(buf-1));
            return -1;
        }
        *next = '\0';
        switch (parsing_state) {
        case ST_NORMAL:
            tok->argv[tok->argc++] = buf;
            break;
        case ST_INFILE:
            tok->infile = buf;
            break;
        case ST_OUTFILE:
            tok->outfile = buf;
            break;
        default:
            (void) fprintf(stderr, "Error: Ambiguous I/O redirection\n");
            return -1;
        }
        parsing_state = ST_NORMAL;
        if (tok->argc >= MAXARGS-1) break;
        buf = next + 1;
    }
    if (parsing_state != ST_NORMAL) {
        (void) fprintf(stderr, "Error: must provide file name for redirection\n");
        return -1;
    }
    tok->argv[tok->argc] = NULL;
    if (tok->argc == 0)  
        return 1;
    if (!strcmp(tok->argv[0], "quit")) {                 
        tok->builtins = BUILTIN_QUIT;
    } else if (!strcmp(tok->argv[0], "jobs")) {          
        tok->builtins = BUILTIN_JOBS;
    } else if (!strcmp(tok->argv[0], "bg")) {            
        tok->builtins = BUILTIN_BG;
    } else if (!strcmp(tok->argv[0], "fg")) {            
        tok->builtins = BUILTIN_FG;
    } else {
        tok->builtins = BUILTIN_NONE;
    }
    if ((is_bg = (*tok->argv[tok->argc-1] == '&')) != 0)
        tok->argv[--tok->argc] = NULL;
    return is_bg;
}
int parseline ( const char * cmdline , struct cmdline_tokens * tok ) { static char array [ MAXLINE ] ; const char delims [ 10 ] = " \t \r \n " ; char * buf = array ; char * next ; char * endbuf ; int is_bg ; int parsing_state ; if ( cmdline == NULL ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } ( void ) strncpy ( buf , cmdline , MAXLINE ) ; endbuf = buf + strlen ( buf ) ; tok -> infile = NULL ; tok -> outfile = NULL ; parsing_state = ST_NORMAL ; tok -> argc = 0 ; while ( buf < endbuf ) { buf += strspn ( buf , delims ) ; if ( buf >= endbuf ) break ; if ( * buf == ' ' ) { if ( tok -> infile ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } parsing_state |= ST_INFILE ; buf ++ ; continue ; } if ( * buf == ' ' ) { if ( tok -> outfile ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } parsing_state |= ST_OUTFILE ; buf ++ ; continue ; } if ( * buf == ' \' ' || * buf == ' \" ' ) { buf ++ ; next = strchr ( buf , * ( buf - 1 ) ) ; } else { next = buf + strcspn ( buf , delims ) ; } if ( next == NULL ) { ( void ) fprintf ( stderr , " \n " , * ( buf - 1 ) ) ; return -1 ; } * next = ' \0 ' ; switch ( parsing_state ) { case ST_NORMAL : tok -> argv [ tok -> argc ++ ] = buf ; break ; case ST_INFILE : tok -> infile = buf ; break ; case ST_OUTFILE : tok -> outfile = buf ; break ; default : ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } parsing_state = ST_NORMAL ; if ( tok -> argc >= MAXARGS - 1 ) break ; buf = next + 1 ; } if ( parsing_state != ST_NORMAL ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } tok -> argv [ tok -> argc ] = NULL ; if ( tok -> argc == 0 ) return 1 ; if ( ! strcmp ( tok -> argv [ 0 ] , " " ) ) { tok -> builtins = BUILTIN_QUIT ; } else if ( ! strcmp ( tok -> argv [ 0 ] , " " ) ) { tok -> builtins = BUILTIN_JOBS ; } else if ( ! strcmp ( tok -> argv [ 0 ] , " " ) ) { tok -> builtins = BUILTIN_BG ; } else if ( ! strcmp ( tok -> argv [ 0 ] , " " ) ) { tok -> builtins = BUILTIN_FG ; } else { tok -> builtins = BUILTIN_NONE ; } if ( ( is_bg = ( * tok -> argv [ tok -> argc - 1 ] == ' ' ) ) != 0 ) tok -> argv [ -- tok -> argc ] = NULL ; return is_bg ; }
parseline - Parse the command line and build the argv array.
parseline - Parse the command line and build the argv array .
/* holds local copy of command line */ /* argument delimiters (white-space) */ /* ptr that traverses command line */ /* ptr to the end of the current arg */ /* ptr to the end of the cmdline string */ /* background job? */ /* indicates if the next token is the
                                            input or output file */ /* Build the argv list */ /* Skip the white-spaces */ /* Check for I/O redirection specifiers */ /* Detect quoted tokens */ /* Find next delimiter */ /* Returned by strchr(); this means that the closing
               quote was not found. */ /* Terminate the token */ /* Record the token as either the next argument or the input/output file */ /* Check if argv is full */ /* The argument list must end with a NULL pointer */ /* ignore blank line */ /* quit command */ /* jobs command */ /* bg command */ /* fg command */ /* Should the job run in the background? */