xref: /haiku/src/tests/add-ons/kernel/file_systems/fs_shell/argv.c (revision 9767c7befda3de757bb92286d61f15d842c9145b)
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 **
28 build_argv(char *str, int *argc)
29 {
30     int table_size = 16, _argc;
31     char *ptr=str;
32     char **argv;
33 
34     if (argc == NULL)
35         argc = &_argc;
36 
37     *argc = 0;
38     argv  = (char **)calloc(table_size, sizeof(char *));
39 
40     if (argv == NULL)
41         return NULL;
42 
43     while(*str) {
44         /* skip intervening white space */
45         while(*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n'))
46             str++;
47 
48         if (*str == '\0')
49             break;
50 
51         if (*str == DOUBLE_QUOTE) {
52             argv[*argc] = ++str;
53             while(*str && *str != DOUBLE_QUOTE) {
54                 if (*str == BACK_SLASH)
55                     strcpy(str, str+1);  /* copy everything down */
56                 str++;
57             }
58         } else if (*str == SINGLE_QUOTE) {
59             argv[*argc] = ++str;
60             while(*str && *str != SINGLE_QUOTE) {
61                 if (*str == BACK_SLASH)
62                     strcpy(str, str+1);  /* copy everything down */
63                 str++;
64             }
65         } else {
66             argv[*argc] = str;
67             while(*str && *str != ' ' && *str != '\t' && *str != '\n') {
68                 if (*str == BACK_SLASH)
69                     strcpy(str, str+1);  /* copy everything down */
70                 str++;
71             }
72         }
73 
74         if (*str != '\0')
75             *str++ = '\0';   /* chop the string */
76 
77         *argc = *argc + 1;
78         if (*argc >= table_size-1) {
79             char **nargv;
80 
81             table_size = table_size * 2;
82             nargv = (char **)calloc(table_size, sizeof(char *));
83 
84             if (nargv == NULL) {   /* drats! failure. */
85                 free(argv);
86                 return NULL;
87             }
88 
89             memcpy(nargv, argv, (*argc) * sizeof(char *));
90             free(argv);
91             argv = nargv;
92         }
93     }
94 
95     return argv;
96 }
97