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