Is this a good C program for splitting a command line without doing any expansion on it? Don't worry too much about main() and the output -- those are for testing.#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <assert.h>void pullwhitespace(char **input);int main (int argc, char **argv){        if (argc != 2) {                fputs(Must have exactly one command line argument\n, stderr);                return 64;        }        char *input = argv[1];        char *outstring = malloc(strlen(argv[1]) + 1);        char *outptr = outstring;        char a;        pullwhitespace(&input);NORMAL:        /* We are in an unquoted part of the input */        switch ((a = *input++))        {        case ' ' :        case '\t':                *outptr++ = '\0';                pullwhitespace(&input);                goto NORMAL;        case '\n':        case '\0':                goto DONE;        case '\\':                if (((a = *input++)) == '\n') {                        break;                } else if (a) {                        *outptr++ = a;                        goto NORMAL;                } else {                        goto FAIL;                }        case '\'':                goto QUOTE;        case '':                goto DQUOTE;        default:                *outptr++ = a;                goto NORMAL;        }        assert(0);QUOTE:        /* We are in a single quoted string */                while (((a = *input++)) != '\'') {                if (a) {                        *outptr++ = a;                } else {                        goto FAIL;                }        }        goto NORMAL;DQUOTE:        /* We are in a double quoted string */        switch ((a = *input++))        {        case '\0':                goto FAIL;        case '\\':        {                char b = *input++;                switch (b)                {                case '\0':                        goto FAIL;                default:                        *outptr++ = a;                              case '':                              case '\\':                        *outptr++ = b;                case '\n':                        break;                }        }        goto DQUOTE;        default:                *outptr++ = a;                goto DQUOTE;        case '':                goto NORMAL;        }        assert(0);FAIL:        fprintf(stderr, %s: Invalid string input\n, argv[0]);        return 1;        assert(0);DONE:        *outptr++ = '\0';        *outptr++ = '\0';        errno = 0;        fwrite(outstring, 1, (size_t)(outptr - outstring), stdout);        int error = errno;        if(ferror(stdout)) {                fprintf(stderr, %s: write error: %s\n, argv[0], strerror(error));                return 1;        }                        fflush(stdout);        if ( errno != 0) {                                fprintf(stderr, %s: write error: %s\n, argv[0], strerror(error));                return 1;        }        return 0;}void pullwhitespace (char **inputptr){        char *input = *inputptr;        char a;        while (( a = *input)) {                if (a != ' ' && a != '\t') {                        return;                }                input++;        }}I know that it is FULL of goto statements (more than every other program I have ever made put together) -- is that okay?The reason for the goto statements is that this is meant as a lightweight state machine. Intended applications include parsing command line arguments or (possibly - this is far fetched) for the parser (not supporting code) to be the basis of a kernel module to parse shebang lines, allowing multiple arguments to be passed to a shebang interpreter.
Splitting a command line in C
c;parsing