From 0ec8c8cea78ff0b08490da2d4d0f968f673cd0a1 Mon Sep 17 00:00:00 2001 From: Greg King Date: Tue, 20 May 2014 16:33:16 -0400 Subject: [PATCH] Added a quoted-token parsing function. --- include/string.h | 12 +++--- libsrc/common/strqtok.c | 86 +++++++++++++++++++++++++++++++++++++ testcode/lib/strqtok-test.c | 49 +++++++++++++++++++++ 3 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 libsrc/common/strqtok.c create mode 100644 testcode/lib/strqtok-test.c diff --git a/include/string.h b/include/string.h index 19cfba27e..be492667e 100644 --- a/include/string.h +++ b/include/string.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2008 Ullrich von Bassewitz */ -/* Roemerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2014, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -81,6 +81,7 @@ char* __fastcall__ strlwr (char* s); char* __fastcall__ strlower (char* s); char* __fastcall__ strupr (char* s); char* __fastcall__ strupper (char* s); +char* __fastcall__ strqtok (char* s1, const char* s2); #endif const char* __fastcall__ _stroserror (unsigned char errcode); @@ -90,6 +91,3 @@ const char* __fastcall__ _stroserror (unsigned char errcode); /* End of string.h */ #endif - - - diff --git a/libsrc/common/strqtok.c b/libsrc/common/strqtok.c new file mode 100644 index 000000000..6e8476b15 --- /dev/null +++ b/libsrc/common/strqtok.c @@ -0,0 +1,86 @@ +/* +** strqtok() is like strtok(): It finds pieces of text, in a string, that are +** surrounded by given delimiter characters. It returns each piece, in turn, +** as a string, until every piece has been found. Then, it returns NULL. But, +** strqtok() recognizes quotation marks. A mark makes delimiters look ordinary +** until another quotation mark is seen. That allows us to include delimiters +** in tokens. (This version doesn't allow escaped quotation marks.) +** +** 2014-04-19, Daniel Serpell +** 2014-04-21, Paul Foerster +** 2014-04-25, Greg King +*/ + + +#include + + +char * __fastcall__ strqtok (register char *s1, const char *s2) +{ + static char c; + static char *start; + static char *next = ""; + + if (s1 == NULL) { + s1 = next; + if (c == '\"') { + goto inQuote; + } + } + + /* Search for the start of a token. */ + while (strchr (s2, c = *s1)) { + if (c == '\0') { + /* No more tokens. */ + return NULL; + } + ++s1; + } + if (c == '\"') { + goto skipQuote; + } + + /* Save the start of the token. */ + start = s1; + + /* Search for the end of a non-quoted token. */ + while ((c = *s1) != '\"' && !strchr (s2, c)) { + ++s1; + } + if (c == '\0') { + /* The end of the last token is the end of the token list; + ** don't go beyond it. + */ + goto found; + } + + /* (A possible begin-quote mark will be rememberred.) */ + goto terminate; + + skipQuote: + ++s1; + + inQuote: + /* Don't let a quote mark be rememberred. */ + c = '\0'; + + /* Save the start of the token. */ + start = s1; + + /* Search for the end of a quoted token. */ + if ((s1 = strchr (s1, '\"')) == NULL) { + /* The quoted token ended with '\0'; therefore, point to a '\0', + ** so that the next call will return NULL. + */ + next = ""; + return start; + } + + terminate: + *s1 = '\0'; + ++s1; + + found: + next = s1; + return start; +} diff --git a/testcode/lib/strqtok-test.c b/testcode/lib/strqtok-test.c new file mode 100644 index 000000000..2c4493dad --- /dev/null +++ b/testcode/lib/strqtok-test.c @@ -0,0 +1,49 @@ +/* strqtok-test.c +** +** 2014-05-20, Greg King +** +** This program tests that strqtok() correctly will parse strings +** with quotation marks in them. It should show this list of tokens +** from the test strings: +** +** >This< +** > is only < +** >a< +** >short< +** >quoting< +** >test , honoring blanks, commas< +** >and< +** >(4)< +** >empty< +** >< +** >< +** >< +** >< +** >strings, EOT < +** +** It shouldn"t show +** +** >Bogus token< +*/ + +#include +#include + +void main(void) +{ + /* b[] and s[] are declared as automatic, not static, variables + ** because strqtok() will change them. + ** They must be defined together; and, b[] must be defined first + ** (because they're copied onto the top-down stack). + */ + char b[] = "Bogus token "; + char s[] = " This , \" is only \"a short " + "quoting\"test , honoring blanks" + ", commas\", and (4) empty \"\"\"\"\"\"\"\" \"strings, EOT "; + char *t = strqtok(s, " ,"); + + while (t != NULL) { + printf(">%s<\n", t); + t = strqtok(NULL, " ,"); + } +} -- 2.39.5