xref: /plan9/sys/src/libc/port/tokenize.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier 
480ee5cbfSDavid du Colombier static char qsep[] = " \t\r\n";
580ee5cbfSDavid du Colombier 
680ee5cbfSDavid du Colombier static char*
qtoken(char * s,char * sep)7*9a747e4fSDavid du Colombier qtoken(char *s, char *sep)
87dd7cddfSDavid du Colombier {
980ee5cbfSDavid du Colombier 	int quoting;
1080ee5cbfSDavid du Colombier 	char *t;
117dd7cddfSDavid du Colombier 
1280ee5cbfSDavid du Colombier 	quoting = 0;
1380ee5cbfSDavid du Colombier 	t = s;	/* s is output string, t is input string */
14*9a747e4fSDavid du Colombier 	while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
1580ee5cbfSDavid du Colombier 		if(*t != '\''){
1680ee5cbfSDavid du Colombier 			*s++ = *t++;
1780ee5cbfSDavid du Colombier 			continue;
187dd7cddfSDavid du Colombier 		}
1980ee5cbfSDavid du Colombier 		/* *t is a quote */
2080ee5cbfSDavid du Colombier 		if(!quoting){
2180ee5cbfSDavid du Colombier 			quoting = 1;
2280ee5cbfSDavid du Colombier 			t++;
2380ee5cbfSDavid du Colombier 			continue;
247dd7cddfSDavid du Colombier 		}
2580ee5cbfSDavid du Colombier 		/* quoting and we're on a quote */
2680ee5cbfSDavid du Colombier 		if(t[1] != '\''){
2780ee5cbfSDavid du Colombier 			/* end of quoted section; absorb closing quote */
2880ee5cbfSDavid du Colombier 			t++;
2980ee5cbfSDavid du Colombier 			quoting = 0;
3080ee5cbfSDavid du Colombier 			continue;
3180ee5cbfSDavid du Colombier 		}
3280ee5cbfSDavid du Colombier 		/* doubled quote; fold one quote into two */
3380ee5cbfSDavid du Colombier 		t++;
3480ee5cbfSDavid du Colombier 		*s++ = *t++;
3580ee5cbfSDavid du Colombier 	}
3680ee5cbfSDavid du Colombier 	if(*s != '\0'){
3780ee5cbfSDavid du Colombier 		*s = '\0';
3880ee5cbfSDavid du Colombier 		if(t == s)
3980ee5cbfSDavid du Colombier 			t++;
4080ee5cbfSDavid du Colombier 	}
4180ee5cbfSDavid du Colombier 	return t;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier 
44*9a747e4fSDavid du Colombier static char*
etoken(char * t,char * sep)45*9a747e4fSDavid du Colombier etoken(char *t, char *sep)
46*9a747e4fSDavid du Colombier {
47*9a747e4fSDavid du Colombier 	int quoting;
48*9a747e4fSDavid du Colombier 
49*9a747e4fSDavid du Colombier 	/* move to end of next token */
50*9a747e4fSDavid du Colombier 	quoting = 0;
51*9a747e4fSDavid du Colombier 	while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
52*9a747e4fSDavid du Colombier 		if(*t != '\''){
53*9a747e4fSDavid du Colombier 			t++;
54*9a747e4fSDavid du Colombier 			continue;
55*9a747e4fSDavid du Colombier 		}
56*9a747e4fSDavid du Colombier 		/* *t is a quote */
57*9a747e4fSDavid du Colombier 		if(!quoting){
58*9a747e4fSDavid du Colombier 			quoting = 1;
59*9a747e4fSDavid du Colombier 			t++;
60*9a747e4fSDavid du Colombier 			continue;
61*9a747e4fSDavid du Colombier 		}
62*9a747e4fSDavid du Colombier 		/* quoting and we're on a quote */
63*9a747e4fSDavid du Colombier 		if(t[1] != '\''){
64*9a747e4fSDavid du Colombier 			/* end of quoted section; absorb closing quote */
65*9a747e4fSDavid du Colombier 			t++;
66*9a747e4fSDavid du Colombier 			quoting = 0;
67*9a747e4fSDavid du Colombier 			continue;
68*9a747e4fSDavid du Colombier 		}
69*9a747e4fSDavid du Colombier 		/* doubled quote; fold one quote into two */
70*9a747e4fSDavid du Colombier 		t += 2;
71*9a747e4fSDavid du Colombier 	}
72*9a747e4fSDavid du Colombier 	return t;
73*9a747e4fSDavid du Colombier }
74*9a747e4fSDavid du Colombier 
75*9a747e4fSDavid du Colombier int
gettokens(char * s,char ** args,int maxargs,char * sep)76*9a747e4fSDavid du Colombier gettokens(char *s, char **args, int maxargs, char *sep)
77*9a747e4fSDavid du Colombier {
78*9a747e4fSDavid du Colombier 	int nargs;
79*9a747e4fSDavid du Colombier 
80*9a747e4fSDavid du Colombier 	for(nargs=0; nargs<maxargs; nargs++){
81*9a747e4fSDavid du Colombier 		while(*s!='\0' && utfrune(sep, *s)!=nil)
82*9a747e4fSDavid du Colombier 			*s++ = '\0';
83*9a747e4fSDavid du Colombier 		if(*s == '\0')
84*9a747e4fSDavid du Colombier 			break;
85*9a747e4fSDavid du Colombier 		args[nargs] = s;
86*9a747e4fSDavid du Colombier 		s = etoken(s, sep);
87*9a747e4fSDavid du Colombier 	}
88*9a747e4fSDavid du Colombier 
89*9a747e4fSDavid du Colombier 	return nargs;
90*9a747e4fSDavid du Colombier }
91*9a747e4fSDavid du Colombier 
927dd7cddfSDavid du Colombier int
tokenize(char * s,char ** args,int maxargs)9380ee5cbfSDavid du Colombier tokenize(char *s, char **args, int maxargs)
94219b2ee8SDavid du Colombier {
9580ee5cbfSDavid du Colombier 	int nargs;
9680ee5cbfSDavid du Colombier 
9780ee5cbfSDavid du Colombier 	for(nargs=0; nargs<maxargs; nargs++){
9880ee5cbfSDavid du Colombier 		while(*s!='\0' && utfrune(qsep, *s)!=nil)
9980ee5cbfSDavid du Colombier 			s++;
10080ee5cbfSDavid du Colombier 		if(*s == '\0')
10180ee5cbfSDavid du Colombier 			break;
10280ee5cbfSDavid du Colombier 		args[nargs] = s;
103*9a747e4fSDavid du Colombier 		s = qtoken(s, qsep);
10480ee5cbfSDavid du Colombier 	}
10580ee5cbfSDavid du Colombier 
10680ee5cbfSDavid du Colombier 	return nargs;
107219b2ee8SDavid du Colombier }
108