xref: /haiku/src/tests/add-ons/kernel/file_systems/fs_shell/argv.c (revision 6c1c51bf87d0f8a7a05e967706d725aa97c0e922)
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