From 59832616362024923be3801bd2039e747f89d7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Fri, 23 May 2014 12:41:15 +0000 Subject: [PATCH] [INTERPRETER] * BUG: Forgot to add two source files. git-svn-id: svn://localhost/gambas/trunk@6287 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- main/gbx/gbx_split.c | 217 +++++++++++++++++++++++++++++++++++++++++++ main/gbx/gbx_split.h | 31 +++++++ 2 files changed, 248 insertions(+) create mode 100644 main/gbx/gbx_split.c create mode 100644 main/gbx/gbx_split.h diff --git a/main/gbx/gbx_split.c b/main/gbx/gbx_split.c new file mode 100644 index 000000000..47427697f --- /dev/null +++ b/main/gbx/gbx_split.c @@ -0,0 +1,217 @@ +/*************************************************************************** + + gbx_split.c + + (c) 2000-2014 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#define __GBX_SPLIT_C + +#include "gb_common.h" +#include "gb_error.h" +#include "gb_array.h" +#include "gbx_c_array.h" + +static CARRAY *_array; +static bool _novoid; +static char *_entry; +static const char *_ptr; +static int _lptr; + +static void add_char_real(const char *p) +{ + if (_lptr) + { + int old_len = STRING_length(_entry); + + _entry = STRING_extend(_entry, old_len + _lptr); + memcpy(&_entry[old_len], _ptr, _lptr); + _entry[old_len + _lptr] = 0; + } + + _ptr = p; + _lptr = p ? 1 : 0; +} + +#define add_char(_p) \ +({ \ + if ((_p) && (_p) == (_ptr + _lptr)) \ + _lptr++; \ + else \ + add_char_real(_p); \ +}) + +static void add_entry() +{ + add_char_real(NULL); + + if (!_entry) + { + if (!_novoid) + ARRAY_add_void((char ***)&_array->data); + } + else + { + *((char **)ARRAY_add((char ***)&_array->data)) = _entry; + _entry = NULL; + } + + //fprintf(stderr, "** add_entry\n"); +} + +static void split_fast(CARRAY *array, const char *str, int lstr, const char *sep, int lsep, bool no_void) +{ + const char *ptr = NULL; + int lptr = 0; + + #define add_entry_fast() \ + ({ \ + if (lptr) \ + { \ + *((char **)ARRAY_add((char ***)&array->data)) = STRING_new(ptr, lptr); \ + lptr = 0; \ + } \ + else if (!no_void) \ + { \ + ARRAY_add_void((char ***)&array->data); \ + } \ + }) + + if (lsep == 1) + { + char csep = sep[0]; + + while (lstr--) + { + if (*str == csep) + { + add_entry_fast(); + } + else + { + if (!lptr) ptr = str; + lptr++; + } + + str++; + } + } + else + { + while (lstr--) + { + if (memchr(sep, *str, lsep)) + { + add_entry_fast(); + } + else + { + if (!lptr) ptr = str; + lptr++; + } + + str++; + } + } + + add_entry_fast(); +} + +CARRAY *STRING_split(const char *str, int lstr, const char *sep, int lsep, const char *esc, int lesc, bool no_void, bool keep_esc) +{ + CARRAY *array; + int i; + char c; + bool escape; + char escl, escr; + + array = OBJECT_create(CLASS_StringArray, NULL, NULL, 0); + if (lstr == 0) + return array; + + if (sep == NULL || lsep == 0) + { + sep = ","; + lsep = 1; + } + + if (esc == NULL || lesc == 0) + { + split_fast(array, str, lstr, sep, lsep, no_void); + } + else + { + _array = array; + _entry = NULL; + _novoid = no_void; + _ptr = NULL; + _lptr = 0; + + escl = esc[0]; + if (lesc >= 2) + escr = esc[1]; + else + escr = escl; + + escape = FALSE; + + for (i = 0; i < lstr; i++) + { + c = *str; + + if (escape) + { + if (c != escr) + add_char(str); + else if ((i < (lstr - 1)) && str[1] == escr) + { + add_char(str); + str++; + i++; + } + else + { + escape = FALSE; + if (keep_esc) + add_char(str); + } + } + else if (c == escl) + { + escape = TRUE; + if (keep_esc) + add_char(str); + } + else if (c == *sep || (lsep > 1 && memchr(&sep[1], c, lsep - 1))) + { + add_entry(); + } + else + add_char(str); + + str++; + } + + add_entry(); + } + + array->count = ARRAY_count(array->data); + + return array; +} diff --git a/main/gbx/gbx_split.h b/main/gbx/gbx_split.h new file mode 100644 index 000000000..88a3255f5 --- /dev/null +++ b/main/gbx/gbx_split.h @@ -0,0 +1,31 @@ +/*************************************************************************** + + gbx_split.h + + (c) 2000-2013 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#ifndef __GBX_SPLIT_H +#define __GBX_SPLIT_H + +#include "gbx_c_array.h" + +CARRAY *STRING_split(const char *str, int lstr, const char *sep, int lsep, const char *esc, int lesc, bool no_void, bool keep_esc); + +#endif \ No newline at end of file