1 /*
2 This file contains a function, build_argv(), which will take an input
3 string and chop it into individual words. The return value is an
4 argv style array (i.e. like what main() receives).
5
6 THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
7 OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
8 NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
9
10 FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
11
12 Dominic Giampaolo
13 dbg@be.com
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <ctype.h>
19 #include <string.h>
20
21 #include "argv.h"
22
23 #define DOUBLE_QUOTE '"'
24 #define SINGLE_QUOTE '\''
25 #define BACK_SLASH '\\'
26
27 char **
build_argv(char * str,int * argc)28 build_argv(char *str, int *argc)
29 {
30 int table_size = 16, _argc;
31 char **argv;
32
33 if (argc == NULL)
34 argc = &_argc;
35
36 *argc = 0;
37 argv = (char **)calloc(table_size, sizeof(char *));
38
39 if (argv == NULL)
40 return NULL;
41
42 while(*str) {
43 /* skip intervening white space */
44 while(*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n'))
45 str++;
46
47 if (*str == '\0')
48 break;
49
50 if (*str == DOUBLE_QUOTE) {
51 argv[*argc] = ++str;
52 while(*str && *str != DOUBLE_QUOTE) {
53 if (*str == BACK_SLASH)
54 strcpy(str, str+1); /* copy everything down */
55 str++;
56 }
57 } else if (*str == SINGLE_QUOTE) {
58 argv[*argc] = ++str;
59 while(*str && *str != SINGLE_QUOTE) {
60 if (*str == BACK_SLASH)
61 strcpy(str, str+1); /* copy everything down */
62 str++;
63 }
64 } else {
65 argv[*argc] = str;
66 while(*str && *str != ' ' && *str != '\t' && *str != '\n') {
67 if (*str == BACK_SLASH)
68 strcpy(str, str+1); /* copy everything down */
69 str++;
70 }
71 }
72
73 if (*str != '\0')
74 *str++ = '\0'; /* chop the string */
75
76 *argc = *argc + 1;
77 if (*argc >= table_size-1) {
78 char **nargv;
79
80 table_size = table_size * 2;
81 nargv = (char **)calloc(table_size, sizeof(char *));
82
83 if (nargv == NULL) { /* drats! failure. */
84 free(argv);
85 return NULL;
86 }
87
88 memcpy(nargv, argv, (*argc) * sizeof(char *));
89 free(argv);
90 argv = nargv;
91 }
92 }
93
94 return argv;
95 }
96