2014-05-23 14:41:15 +02:00
|
|
|
/***************************************************************************
|
|
|
|
|
|
|
|
gbx_split.c
|
|
|
|
|
2018-02-12 02:53:46 +01:00
|
|
|
(c) 2000-2017 Benoît Minisini <g4mba5@gmail.com>
|
2014-05-23 14:41:15 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
if (escr == *sep)
|
2014-05-23 14:41:15 +02:00
|
|
|
{
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
for (i = 0; i < lstr; i++)
|
2014-05-23 14:41:15 +02:00
|
|
|
{
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
c = *str;
|
|
|
|
|
|
|
|
if (c == escl)
|
2014-05-23 14:41:15 +02:00
|
|
|
{
|
|
|
|
i++;
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
str++;
|
|
|
|
if (i < lstr)
|
|
|
|
add_char(str);
|
|
|
|
}
|
|
|
|
else if (c == *sep || (lsep > 1 && memchr(&sep[1], c, lsep - 1)))
|
|
|
|
{
|
|
|
|
add_entry();
|
2014-05-23 14:41:15 +02:00
|
|
|
}
|
|
|
|
else
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
add_char(str);
|
|
|
|
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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)
|
2014-05-23 14:41:15 +02:00
|
|
|
{
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
escape = TRUE;
|
2014-05-23 14:41:15 +02:00
|
|
|
if (keep_esc)
|
|
|
|
add_char(str);
|
|
|
|
}
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
else if (c == *sep || (lsep > 1 && memchr(&sep[1], c, lsep - 1)))
|
|
|
|
{
|
|
|
|
add_entry();
|
|
|
|
}
|
|
|
|
else
|
2014-05-23 14:41:15 +02:00
|
|
|
add_char(str);
|
[DEVELOPMENT ENVIRONMENT]
* NEW: Software farm: Software now can be safely installed or removed. The
source checksum is checked, as well as the required components. Libraries
and dependencies on other software are not yet taken into account. A
'*.desktop' file is automatically created on installation now.
[INTERPRETER]
* NEW: Split() has a new behaviour when its escape argument has two
characters, the second one being the first splitting character. It uses
the first character to escape splitting characters. For example,
Split("a;b~;c;d",";","~;") returns ["a","b;c","d"].
* NEW: String[].Join() method handle the new Split syntax.
["a","b;c","d"].Join(";","~;") returns "a;b~;c;d". Moreover, in the
traditional escape syntax, the joined string are not escaped anymore if
they are void.
[GB.DESKTOP]
* NEW: DesktopFile.MimeTypes is a new property corresponding to the
'MimeType' entry of the '*.desktop' file.
* NEW: DesktopFile now can be used for creating or modifying '*.desktop'
files.
git-svn-id: svn://localhost/gambas/trunk@6689 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2014-11-30 01:30:32 +01:00
|
|
|
|
|
|
|
str++;
|
2014-05-23 14:41:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
add_entry();
|
|
|
|
}
|
|
|
|
|
|
|
|
array->count = ARRAY_count(array->data);
|
|
|
|
|
|
|
|
return array;
|
|
|
|
}
|