199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Jordan K. Hubbard
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 29 August 1998
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The meat of the simple parser.
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void clean(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define PARSE_BUFSIZE 1024 /* maximum size of one element */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define MAXARGS 20 /* maximum number of elements */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * parse: accept a string of input and "parse" it for backslash
199767f8919635c4928607450d9e0abb932109ceToomas Soome * substitutions and environment variable expansions (${var}),
199767f8919635c4928607450d9e0abb932109ceToomas Soome * returning an argc/argv style vector of whitespace separated
199767f8919635c4928607450d9e0abb932109ceToomas Soome * arguments. Returns 0 on success, 1 on failure (ok, ok, so I
199767f8919635c4928607450d9e0abb932109ceToomas Soome * wimped-out on the error codes! :).
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Note that the argv array returned must be freed by the caller, but
199767f8919635c4928607450d9e0abb932109ceToomas Soome * we own the space allocated for arguments and will free that on next
199767f8919635c4928607450d9e0abb932109ceToomas Soome * invocation. This allows argv consumers to modify the array if
199767f8919635c4928607450d9e0abb932109ceToomas Soome * NB: environment variables that expand to more than one whitespace
199767f8919635c4928607450d9e0abb932109ceToomas Soome * separated token will be returned as a single argv[] element, not
199767f8919635c4928607450d9e0abb932109ceToomas Soome * split in turn. Expanded text is also immune to further backslash
199767f8919635c4928607450d9e0abb932109ceToomas Soome * elimination or expansion since this is a one-pass, non-recursive
199767f8919635c4928607450d9e0abb932109ceToomas Soome * parser. You didn't specify more than this so if you want more, ask
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Accept the usual delimiters for a variable, returning counterpart */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return '\0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!str || (p = copy = backslash(str)) == NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Initialize vector and state */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* And awaaaaaaaaay we go! */
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (*p) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf[i++] = *p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if (isquote(*p)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf[i++] = *p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if (isdquote(*p)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf[i++] = *p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome buf[i++] = *p++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (*q && !isspace(*q))
199767f8919635c4928607450d9e0abb932109ceToomas Soome strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* missing terminating ' or " */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* If at end of token, add it */
199767f8919635c4928607450d9e0abb932109ceToomas Soome *argv = (char **)malloc((sizeof(char *) * ac + 1));
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Clean vector space */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < MAXARGS; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* XXX search "special variable" space first? */