commit dbc5007c9dd9bfabad376d74e55b9f2c65584a64
parent 449ca59fe7a945f625cdccb3a7e0dfa278a9af5b
Author: sin <sin@2f30.org>
Date: Tue, 6 May 2014 13:27:22 +0100
Add tokenize functions from Plan9
Diffstat:
M | Makefile | | | 2 | +- |
M | ds.h | | | 4 | ++++ |
A | tokenize.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;
+}