gambas-source-code/main/gbx/gbx_split.c
Benoît Minisini 03cd222bb8 [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 00:30:32 +00:00

243 lines
4.1 KiB
C

/***************************************************************************
gbx_split.c
(c) 2000-2014 Benoît Minisini <gambas@users.sourceforge.net>
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;
if (escr == *sep)
{
for (i = 0; i < lstr; i++)
{
c = *str;
if (c == escl)
{
i++;
str++;
if (i < lstr)
add_char(str);
}
else if (c == *sep || (lsep > 1 && memchr(&sep[1], c, lsep - 1)))
{
add_entry();
}
else
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)
{
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;
}