libds

a collection of simple data structures
Log | Files | Refs | LICENSE

commit dbc5007c9dd9bfabad376d74e55b9f2c65584a64
parent 449ca59fe7a945f625cdccb3a7e0dfa278a9af5b
Author: sin <sin@2f30.org>
Date:   Tue,  6 May 2014 13:27:22 +0100

Add tokenize functions from Plan9

Diffstat:
MMakefile | 2+-
Mds.h | 4++++
Atokenize.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = fifo.c stack.c vector.c +SRC = fifo.c stack.c tokenize.c vector.c OBJ = ${SRC:.c=.o} SOUT = ${NAME}.a diff --git a/ds.h b/ds.h @@ -16,6 +16,10 @@ void *stack_push(struct stack *, void *); void *stack_pop(struct stack *); void *stack_peek(struct stack *); +/* tokenize.c */ +int gettokens(char *, char **, int, char *); +int tokenize(char *, char **, int); + /* vector.c */ struct vector *vector_init(void); void vector_free(struct vector *); diff --git a/tokenize.c b/tokenize.c @@ -0,0 +1,107 @@ +/* Licensed under GPLv2, taken from Plan9 */ +#include <string.h> + +static char qsep[] = " \t\r\n"; + +static char* +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 || strchr(sep, *t)==NULL)) { + if(*t != '\'') { + *s++ = *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++; + *s++ = *t++; + } + if(*s != '\0') { + *s = '\0'; + if(t == s) + t++; + } + return t; +} + +static char* +etoken(char *t, char *sep) +{ + int quoting; + + /* move to end of next token */ + quoting = 0; + while(*t!='\0' && (quoting || strchr(sep, *t)==NULL)) { + 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' && strchr(sep, *s)!=NULL) + *s++ = '\0'; + if(*s == '\0') + break; + args[nargs] = s; + s = etoken(s, sep); + } + + return nargs; +} + +int +tokenize(char *s, char **args, int maxargs) +{ + int nargs; + + for(nargs=0; nargs<maxargs; nargs++) { + while(*s!='\0' && strchr(qsep, *s)!=NULL) + s++; + if(*s == '\0') + break; + args[nargs] = s; + s = qtoken(s, qsep); + } + + return nargs; +}