ast_comparator/test/student_data/handout/shlab-handout/cases/reference_26_tsh.c
/*
 * parseline - Parse the command line and build the argv array.
 *
 * Parameters:
 *   cmdline:  The command line, in the form:
 *
 *                command [arguments...] [< infile] [> oufile] [&]
 *
 *   cmd_tokens:      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 cmd_tokens (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.
Parameters:
cmdline:  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 cmd_tokens
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 . Parameters : cmdline : 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 cmd_tokens are statically allocated inside parseline () and will be overwritten the next time this function is invoked .
int parseline(const char *cmdline, struct cmdline_tokens *cmd_tokens) {
    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);
    cmd_tokens->infile = NULL;
    cmd_tokens->outfile = NULL;
    parsing_state = ST_NORMAL;
    cmd_tokens->argc = 0;
    while (buf < endbuf) {
        buf += strspn (buf, delims);
        if (buf >= endbuf) break;
        if (*buf == '<') {
            if (cmd_tokens->infile) {
                (void) fprintf(stderr, "Error: Ambiguous I/O redirection\n");
                return -1;
            }
            parsing_state |= ST_INFILE;
            buf++;
            continue;
        }
        if (*buf == '>') {
            if (cmd_tokens->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:
                cmd_tokens->argv[cmd_tokens->argc++] = buf;
                break;
            case ST_INFILE:
                cmd_tokens->infile = buf;
                break;
            case ST_OUTFILE:
                cmd_tokens->outfile = buf;
                break;
            default:
                (void) fprintf(stderr, "Error: Ambiguous I/O redirection\n");
                return -1;
        }
        parsing_state = ST_NORMAL;
        if (cmd_tokens->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;
    }
    cmd_tokens->argv[cmd_tokens->argc] = NULL;
    if (cmd_tokens->argc == 0)  
        return 1;
    if (!strcmp(cmd_tokens->argv[0], "quit")) {                 
        cmd_tokens->builtins = BUILTIN_QUIT;
    } else if (!strcmp(cmd_tokens->argv[0], "jobs")) {          
        cmd_tokens->builtins = BUILTIN_JOBS;
    } else if (!strcmp(cmd_tokens->argv[0], "bg")) {            
        cmd_tokens->builtins = BUILTIN_BG;
    } else if (!strcmp(cmd_tokens->argv[0], "fg")) {            
        cmd_tokens->builtins = BUILTIN_FG;
    } else {
        cmd_tokens->builtins = BUILTIN_NONE;
    }
    if ((is_bg = (*cmd_tokens->argv[cmd_tokens->argc-1] == '&')) != 0)
        cmd_tokens->argv[--cmd_tokens->argc] = NULL;
    return is_bg;
}
int parseline ( const char * cmdline , struct cmdline_tokens * cmd_tokens ) { 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 ) ; cmd_tokens -> infile = NULL ; cmd_tokens -> outfile = NULL ; parsing_state = ST_NORMAL ; cmd_tokens -> argc = 0 ; while ( buf < endbuf ) { buf += strspn ( buf , delims ) ; if ( buf >= endbuf ) break ; if ( * buf == ' ' ) { if ( cmd_tokens -> infile ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } parsing_state |= ST_INFILE ; buf ++ ; continue ; } if ( * buf == ' ' ) { if ( cmd_tokens -> 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 : cmd_tokens -> argv [ cmd_tokens -> argc ++ ] = buf ; break ; case ST_INFILE : cmd_tokens -> infile = buf ; break ; case ST_OUTFILE : cmd_tokens -> outfile = buf ; break ; default : ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } parsing_state = ST_NORMAL ; if ( cmd_tokens -> argc >= MAXARGS - 1 ) break ; buf = next + 1 ; } if ( parsing_state != ST_NORMAL ) { ( void ) fprintf ( stderr , " \n " ) ; return -1 ; } cmd_tokens -> argv [ cmd_tokens -> argc ] = NULL ; if ( cmd_tokens -> argc == 0 ) return 1 ; if ( ! strcmp ( cmd_tokens -> argv [ 0 ] , " " ) ) { cmd_tokens -> builtins = BUILTIN_QUIT ; } else if ( ! strcmp ( cmd_tokens -> argv [ 0 ] , " " ) ) { cmd_tokens -> builtins = BUILTIN_JOBS ; } else if ( ! strcmp ( cmd_tokens -> argv [ 0 ] , " " ) ) { cmd_tokens -> builtins = BUILTIN_BG ; } else if ( ! strcmp ( cmd_tokens -> argv [ 0 ] , " " ) ) { cmd_tokens -> builtins = BUILTIN_FG ; } else { cmd_tokens -> builtins = BUILTIN_NONE ; } if ( ( is_bg = ( * cmd_tokens -> argv [ cmd_tokens -> argc - 1 ] == ' ' ) ) != 0 ) cmd_tokens -> argv [ -- cmd_tokens -> 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 .
// TODO: find tutorial link and add here /* Changing parseline to parse struct cmd_tokens */ /* 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 end of 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 i/o 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? */