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