xref: /plan9/sys/src/cmd/unix/drawterm/libc/tokenize.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
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