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