1 #include <u.h>
2 #include <libc.h>
3
4 static char qsep[] = " \t\r\n";
5
6 static char*
qtoken(char * s,char * sep)7 qtoken(char *s, char *sep)
8 {
9 int quoting;
10 char *t;
11
12 quoting = 0;
13 t = s; /* s is output string, t is input string */
14 while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
15 if(*t != '\''){
16 *s++ = *t++;
17 continue;
18 }
19 /* *t is a quote */
20 if(!quoting){
21 quoting = 1;
22 t++;
23 continue;
24 }
25 /* quoting and we're on a quote */
26 if(t[1] != '\''){
27 /* end of quoted section; absorb closing quote */
28 t++;
29 quoting = 0;
30 continue;
31 }
32 /* doubled quote; fold one quote into two */
33 t++;
34 *s++ = *t++;
35 }
36 if(*s != '\0'){
37 *s = '\0';
38 if(t == s)
39 t++;
40 }
41 return t;
42 }
43
44 static char*
etoken(char * t,char * sep)45 etoken(char *t, char *sep)
46 {
47 int quoting;
48
49 /* move to end of next token */
50 quoting = 0;
51 while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
52 if(*t != '\''){
53 t++;
54 continue;
55 }
56 /* *t is a quote */
57 if(!quoting){
58 quoting = 1;
59 t++;
60 continue;
61 }
62 /* quoting and we're on a quote */
63 if(t[1] != '\''){
64 /* end of quoted section; absorb closing quote */
65 t++;
66 quoting = 0;
67 continue;
68 }
69 /* doubled quote; fold one quote into two */
70 t += 2;
71 }
72 return t;
73 }
74
75 int
gettokens(char * s,char ** args,int maxargs,char * sep)76 gettokens(char *s, char **args, int maxargs, char *sep)
77 {
78 int nargs;
79
80 for(nargs=0; nargs<maxargs; nargs++){
81 while(*s!='\0' && utfrune(sep, *s)!=nil)
82 *s++ = '\0';
83 if(*s == '\0')
84 break;
85 args[nargs] = s;
86 s = etoken(s, sep);
87 }
88
89 return nargs;
90 }
91
92 int
tokenize(char * s,char ** args,int maxargs)93 tokenize(char *s, char **args, int maxargs)
94 {
95 int nargs;
96
97 for(nargs=0; nargs<maxargs; nargs++){
98 while(*s!='\0' && utfrune(qsep, *s)!=nil)
99 s++;
100 if(*s == '\0')
101 break;
102 args[nargs] = s;
103 s = qtoken(s, qsep);
104 }
105
106 return nargs;
107 }
108