summaryrefslogtreecommitdiff
path: root/lib9/tokenize.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9/tokenize.c')
-rw-r--r--lib9/tokenize.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/lib9/tokenize.c b/lib9/tokenize.c
index 1b222c52..790b7c2a 100644
--- a/lib9/tokenize.c
+++ b/lib9/tokenize.c
@@ -3,14 +3,14 @@
static char qsep[] = " \t\r\n";
static char*
-qtoken(char *s)
+qtoken(char *s, char *sep)
{
int quoting;
char *t;
quoting = 0;
t = s; /* s is output string, t is input string */
- while(*t!='\0' && (quoting || utfrune(qsep, *t)==nil)){
+ while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
if(*t != '\''){
*s++ = *t++;
continue;
@@ -40,6 +40,54 @@ qtoken(char *s)
return t;
}
+static char*
+etoken(char *t, char *sep)
+{
+ int quoting;
+
+ /* move to end of next token */
+ quoting = 0;
+ while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
+ if(*t != '\''){
+ t++;
+ continue;
+ }
+ /* *t is a quote */
+ if(!quoting){
+ quoting = 1;
+ t++;
+ continue;
+ }
+ /* quoting and we're on a quote */
+ if(t[1] != '\''){
+ /* end of quoted section; absorb closing quote */
+ t++;
+ quoting = 0;
+ continue;
+ }
+ /* doubled quote; fold one quote into two */
+ t += 2;
+ }
+ return t;
+}
+
+int
+gettokens(char *s, char **args, int maxargs, char *sep)
+{
+ int nargs;
+
+ for(nargs=0; nargs<maxargs; nargs++){
+ while(*s!='\0' && utfrune(sep, *s)!=nil)
+ *s++ = '\0';
+ if(*s == '\0')
+ break;
+ args[nargs] = s;
+ s = etoken(s, sep);
+ }
+
+ return nargs;
+}
+
int
tokenize(char *s, char **args, int maxargs)
{
@@ -51,7 +99,7 @@ tokenize(char *s, char **args, int maxargs)
if(*s == '\0')
break;
args[nargs] = s;
- s = qtoken(s);
+ s = qtoken(s, qsep);
}
return nargs;