29#define DISABLE_DEBUGLOG
51#include <gwenhywfar/gwenhywfarapi.h>
52#include <gwenhywfar/debug.h>
53#include <gwenhywfar/stringlist.h>
80static int _cmpSegment(
const char *w,
unsigned int *wpos,
81 const char *p,
unsigned int *ppos,
83 unsigned int *matches);
84static int _findSegment(
const char *w,
unsigned int *wpos,
85 const char *p,
unsigned int *ppos,
87 unsigned int *matches);
103 unsigned int maxsize,
117 while (*src && (
unsigned char)(*src)<33)
134 while (*src && size<(maxsize-1)) {
149 if (!insideQuotes && strchr(delims, *src)!=0)
159 "Found a closing \" without an opening one "
160 "(consider using a backslash to escape)");
177 if (isspace((
int)((
unsigned char)*src)) && !lastWasEscape) {
201 if (strchr(delims, *src)==0) {
216 if (lastBlankPos!=-1)
217 buffer[lastBlankPos]=0;
232 const char *savedSrc=src;
240 while (*src && (
unsigned char)(*src)<33) {
241 if (strchr(delims, *src)) {
275 if (!insideQuotes && strchr(delims, *src)!=0)
285 "Found a closing \" without an opening one "
286 "(consider using a backslash to escape)");
303 if (!lastWasEscape && *((
unsigned char *)src)<33) {
324 if (strchr(delims, *src)==0) {
339 if (lastBlankPos!=-1)
351 unsigned int maxsize)
359 x=(
unsigned char)*src;
361 (x>=
'A' && x<=
'Z') ||
362 (x>=
'a' && x<=
'z') ||
363 (x>=
'0' && x<=
'9'))) {
366 if ((maxsize-1)<size+3) {
371 c=(((
unsigned char)(*src))>>4)&0xf;
376 c=((
unsigned char)(*src))&0xf;
383 if (size<(maxsize-1))
402 unsigned int maxsize)
410 x=(
unsigned char)*src;
412 (x>=
'A' && x<=
'Z') ||
413 (x>=
'a' && x<=
'z') ||
414 (x>=
'0' && x<=
'9') ||
424 if ((maxsize-1)<size+3) {
429 c=(((
unsigned char)(*src))>>4)&0xf;
434 c=((
unsigned char)(*src))&0xf;
441 if (size<(maxsize-1))
461 unsigned int maxsize)
467 while (*src && srclen>0) {
470 x=(
unsigned char)*src;
472 (x>=
'A' && x<=
'Z') ||
473 (x>=
'a' && x<=
'z') ||
474 (x>=
'0' && x<=
'9')) {
475 if (size<(maxsize-1))
484 unsigned char d1, d2;
493 if (!(*src) || !isxdigit((
int)*src)) {
498 d1=(
unsigned char)(toupper(*src));
502 if (!(*src) || !isxdigit((
int)*src)) {
506 d2=(
unsigned char)(toupper(*src));
517 if (size<(maxsize-1))
518 buffer[size++]=(char)c;
527 "characters in escaped string (\"%s\")",
544 unsigned int maxsize)
557 unsigned int maxsize)
563 while (*src && srclen>0) {
566 x=(
unsigned char)*src;
568 (x>=
'A' && x<=
'Z') ||
569 (x>=
'a' && x<=
'z') ||
570 (x>=
'0' && x<=
'9') ||
578 if (size<(maxsize-1))
587 unsigned char d1, d2;
596 if (!(*src) || !isxdigit((
int)*src)) {
601 d1=(
unsigned char)(toupper(*src));
605 if (!(*src) || !isxdigit((
int)*src)) {
609 d2=(
unsigned char)(toupper(*src));
620 if (size<(maxsize-1))
621 buffer[size++]=(char)c;
630 "characters in escaped string (\"%s\")",
647 unsigned int maxsize)
658 char *buffer,
unsigned int maxsize)
663 if ((l*2)+1 > maxsize) {
673 c=(((
unsigned char)(src[pos]))>>4)&0xf;
678 c=((
unsigned char)(src[pos]))&0xf;
695 unsigned int groupsize,
697 int skipLeadingZeroes)
713 c=(((
unsigned char)(src[pos]))>>4)&0xf;
714 if (skipLeadingZeroes) {
724 if (size+1>=maxsize) {
731 if (size+1>=maxsize) {
735 buffer[size++]=delimiter;
741 c=((
unsigned char)(src[pos]))&0xf;
742 if (skipLeadingZeroes) {
751 if (size+1>=maxsize) {
760 if (size+1>=maxsize) {
764 buffer[size++]=delimiter;
779 unsigned int groupsize,
781 int skipLeadingZeroes)
783 unsigned int pos = 0;
791 c=(((
unsigned char)(src[pos]))>>4)&0xf;
792 if (skipLeadingZeroes) {
807 if (groupsize && j==groupsize) {
817 c=((
unsigned char)(src[pos]))&0xf;
818 if (skipLeadingZeroes) {
833 if (groupsize && j==groupsize) {
852 unsigned int size = 0;
855 unsigned char d1, d2;
859 if (!isxdigit((
int)*src)) {
863 d1=(
unsigned char)(toupper(*src));
867 if (!(*src) || !isxdigit((
int)*src)) {
871 d2=(
unsigned char)(toupper(*src));
885 buffer[size++]=(char)c;
900 unsigned char d1, d2;
904 if (isspace((
int)*src)) {
908 if (!isxdigit((
int)*src)) {
912 d1=(
unsigned char)(toupper(*src));
916 if (!(*src) || !isxdigit((
int)*src)) {
920 d2=(
unsigned char)(toupper(*src));
950 unsigned char d1, d2;
959 if (!isdigit((
int)*src)) {
963 d1=(
unsigned char)(*src);
967 if (!(*src) || !isxdigit((
int)*src)) {
971 d2=(
unsigned char)(*src);
990 unsigned int groupsize,
992 int skipLeadingZeroes)
1006 c=(((
unsigned char)(src[pos]))>>4)&0xf;
1007 if (skipLeadingZeroes) {
1011 skipLeadingZeroes=0;
1020 if (groupsize && j==groupsize) {
1030 c=((
unsigned char)(src[pos]))&0xf;
1031 if (skipLeadingZeroes) {
1032 if (c==0 && pos+1<l)
1035 skipLeadingZeroes=0;
1044 if (groupsize && j==groupsize) {
1076 return strcasecmp(s1, s2);
1078 return strcmp(s1, s2);
1086 while (*haystack && tolower(*haystack)!=tolower(*needle))
1097 while (*t && *s && (tolower(*t)==tolower(*s))) {
1119 const char *p,
unsigned int *ppos,
1121 unsigned int *matches)
1128 unsigned int _wpos = *wpos, _ppos = *ppos, _matches = *matches;
1135 while (_wpos<wlength && _ppos<plength) {
1141 *matches = _matches;
1151 if (a!=b && b!=
'?') {
1154 *matches = _matches;
1161 if (_wpos==wlength && _ppos==plength) {
1164 *matches = _matches;
1168 if (_wpos>=wlength && _ppos<plength)
1169 if (p[_ppos]==
'*') {
1172 *matches = _matches;
1178 *matches = _matches;
1185 const char *p,
unsigned int *ppos,
1187 unsigned int *matches)
1189 unsigned int lwpos, lppos, lmatches;
1196 while (lwpos<wlength) {
1200 if (
_cmpSegment(w, wpos, p, ppos, sensecase, matches))
1212 unsigned int matches;
1213 unsigned int plength;
1215 ppos=wpos=matches=0;
1219 if (!
_cmpSegment(w, &wpos, p, &ppos, sensecase, &matches)) {
1233 if (!
_findSegment(w, &wpos, p, &ppos, sensecase, &matches)) {
1249 sprintf(lbuffer,
"%d", num);
1257 strcpy(buffer, lbuffer);
1259 buffer[i++]=fillchar;
1263 else if (fillchar<0) {
1271 strcat(buffer, lbuffer);
1276 strcpy(buffer, lbuffer);
1284 unsigned int insert)
1292 for (k=0; k<insert; k++)
1293 fprintf(stderr,
" ");
1294 fprintf(stderr,
"String size is %d:\n", l);
1296 for (k=0; k<insert; k++)
1297 fprintf(stderr,
" ");
1298 fprintf(stderr,
"%04x: ", pos);
1304 for (i=pos; i<j; i++) {
1305 fprintf(stderr,
"%02x ", (
unsigned char)s[i]);
1308 for (i=0; i<16-(j-pos); i++)
1309 fprintf(stderr,
" ");
1311 for (i=pos; i<j; i++) {
1313 fprintf(stderr,
".");
1315 fprintf(stderr,
"%c", s[i]);
1317 fprintf(stderr,
"\n");
1326 unsigned int insert)
1335 for (k=0; k<insert; k++)
1338 snprintf(numbuf,
sizeof(numbuf),
"%d", l);
1342 for (k=0; k<insert; k++)
1344 snprintf(numbuf,
sizeof(numbuf),
"%04x: ", pos);
1351 for (i=pos; i<j; i++) {
1352 snprintf(numbuf,
sizeof(numbuf),
"%02x ", (
unsigned char)s[i]);
1356 for (i=0; i<16-(j-pos); i++)
1359 for (i=pos; i<j; i++) {
1381 x=(
unsigned char)*src;
1383 (x>=
'A' && x<=
'Z') ||
1384 (x>=
'a' && x<=
'z') ||
1385 (x>=
'0' && x<=
'9'))) {
1389 c=(((
unsigned char)(*src))>>4)&0xf;
1394 c=((
unsigned char)(*src))&0xf;
1416 x=(
unsigned char)*src;
1418 (x>=
'A' && x<=
'Z') ||
1419 (x>=
'a' && x<=
'z') ||
1420 (x>=
'0' && x<=
'9')) {
1425 unsigned char d1, d2;
1430 if (!(*src) || !isxdigit((
int)*src)) {
1435 d1=(
unsigned char)(toupper(*src));
1439 if (!(*src) || !isxdigit((
int)*src)) {
1443 d2=(
unsigned char)(toupper(*src));
1458 "characters in escaped string (\"%s\")",
1476 x=(
unsigned char)*src;
1478 (x>=
'A' && x<=
'Z') ||
1479 (x>=
'a' && x<=
'z') ||
1480 (x>=
'0' && x<=
'9') ||
1493 c=(((
unsigned char)(*src))>>4)&0xf;
1498 c=((
unsigned char)(*src))&0xf;
1522 if (strlen(src)>2) {
1523 unsigned char d1, d2;
1526 if (isxdigit((
int)src[1]) && isxdigit((
int)src[2])) {
1530 d1=(
unsigned char)(toupper(*src));
1534 d2=(
unsigned char)(toupper(*src));
1573 (x>=
'A' && x<=
'Z') ||
1574 (x>=
'a' && x<=
'z') ||
1575 (x>=
'0' && x<=
'9') ||
1586 c=(((
unsigned char)x)>>4)&0xf;
1591 c=((
unsigned char)x)&0xf;
1607 const char *logDomain,
1635 for (i=0; i<size; i++) {
1637 if (isspace((
int)*p)) {
1638 if (!lastWasBlank) {
1654 if (lastBlankPos!=0)
1667#ifdef HAVE_SETLOCALE
1668 const char *orig_locale = setlocale(LC_NUMERIC,
NULL);
1669 char *currentLocale = strdup(orig_locale ? orig_locale :
"C");
1670 setlocale(LC_NUMERIC,
"C");
1673 rv=snprintf(numbuf,
sizeof(numbuf),
"%f", num);
1675#ifdef HAVE_SETLOCALE
1676 setlocale(LC_NUMERIC, currentLocale);
1677 free(currentLocale);
1680 if (rv<1 || rv>=(
int)
sizeof(numbuf))
1691#ifdef HAVE_SETLOCALE
1692 const char *orig_locale = setlocale(LC_NUMERIC,
NULL);
1693 char *currentLocale = strdup(orig_locale ? orig_locale :
"C");
1694 setlocale(LC_NUMERIC,
"C");
1697 rv=sscanf(s,
"%lf", num);
1699#ifdef HAVE_SETLOCALE
1700 setlocale(LC_NUMERIC, currentLocale);
1701 free(currentLocale);
1717 nboth=strlen(s1)+strlen(s2);
1720 while (*s1 && *s2) {
1728 if (toupper(*s1)==toupper(*t)) {
1732 if (isalnum((
int)*s1) && isalnum((
int)*t)) {
1748 while (*s1 && *s2) {
1760 if (toupper(*s1)==toupper(*t)) {
1764 if (isalnum((
int)*s1) && isalnum((
int)*t)) {
1780 pc=(nmatch*100)/nboth;
1808 while (handled<len) {
1812 c=(
unsigned char)*s;
1813 if ((c & 0xfe)==0xfc)
1815 else if ((c & 0xfc)==0xf8)
1817 else if ((c & 0xf8)==0xf0)
1819 else if ((c & 0xf0)==0xe0)
1821 else if ((c & 0xe0)==0xc0)
1823 else if (c & 0x80) {
1829 if (handled+i+1>len) {
1831 "Incomplete UTF8 sequence at pos %d", handled);
1838 for (j=0; j<i; j++) {
1839 if ((((
unsigned char)*s) & 0xc0)!=0xc0) {
1841 "Invalid UTF8 sequence at pos %d (rel %d of %d)",
1860 uint32_t bytesAdded;
1862#define GWEN_TEXT__APPENDCHAR(chr) \
1865 GWEN_Buffer_IncrementPos(buf, bytesAdded); \
1866 GWEN_Buffer_AdjustUsedBytes(buf); \
1868 GWEN_Buffer_AllocRoom(buf, 2); \
1869 pdst=GWEN_Buffer_GetPosPointer(buf); \
1870 roomLeft=GWEN_Buffer_GetMaxUnsegmentedWrite(buf); \
1873 *(pdst++)=(unsigned char)chr; \
1887 x=(
unsigned char)*src;
1890 unsigned char num=0;
1894 while (*src && isdigit((
int)*src)) {
1902 else if (strncmp(src+1,
"szlig;", 6)==0) {
1908 else if (strncmp(src+1,
"Auml;", 5)==0) {
1914 else if (strncmp(src+1,
"Ouml;", 5)==0) {
1920 else if (strncmp(src+1,
"Uuml;", 5)==0) {
1926 else if (strncmp(src+1,
"auml;", 5)==0) {
1932 else if (strncmp(src+1,
"ouml;", 5)==0) {
1938 else if (strncmp(src+1,
"uuml;", 5)==0) {
1951 if (strncasecmp(src, e->
replace, l)==0) {
1973#undef GWEN_TEXT__APPENDCHAR
1986 x=(
unsigned char)*src;
2001 snprintf(numbuf,
sizeof(numbuf),
"&#%d;", x);
2016 const char *toCharset,
2017 const char *text,
int len,
2021 if (fromCharset && *fromCharset && toCharset && *toCharset &&
2022 strcasecmp(fromCharset, toCharset)!=0) {
2025 "iconv not available, can not convert from \"%s\" to \"%s\"",
2026 fromCharset, toCharset);
2030 ic=iconv_open(toCharset, fromCharset);
2031 if (ic==((iconv_t)-1)) {
2033 fromCharset, toCharset);
2049 pInbuf=(
char *)text;
2053 outbuf=(
char *)malloc(outLeft);
2057 pInbuf=(
char *)text;
2059 done=iconv(ic, &pInbuf, &inLeft, &pOutbuf, &outLeft);
2060 if (done==(
size_t)-1) {
2062 strerror(errno), errno);
2093 p=memchr(s,
'\0', n);
2103 return strndup(s, n);
2125 while (*p && *p!=
')')
2138 uint32_t posBeforeFn;
2139 uint32_t posAfterFn;
2140 uint32_t charsAdded;
2147 rawName=(
char *) malloc(len+1);
2149 memmove(rawName, pStart, len);
2169 charsAdded=posAfterFn-posBeforeFn;
2170 if (maxLen>0 && (
int)charsAdded>maxLen) {
2203 while (*p && *p!=
'[' && *p!=
':')
2211 name=(
char *) malloc(len+1);
2213 memmove(name, pStart, len);
2220 while (*p && *p!=
']' && isdigit(*p)) {
2240 while (*p && isdigit(*p)) {
2252 *pVariableName=name;
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
#define DBG_INFO(dbg_logger, format,...)
#define DBG_ERROR(dbg_logger, format,...)
#define DBG_DEBUG(dbg_logger, format,...)
#define GWEN_ERROR_BAD_DATA
#define GWEN_ERROR_NO_ADDRESS
#define GWEN_ERROR_GENERIC
#define GWEN_ERROR_NO_DATA
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
void GWEN_Logger_Log(const char *logDomain, GWEN_LOGGER_LEVEL priority, const char *s)
double GWEN_Text_CheckSimilarity(const char *s1, const char *s2, int ign)
char * GWEN_Text_strndup(const char *s, size_t n)
#define GWEN_TEXT__APPENDCHAR(chr)
int GWEN_Text_UnescapeXmlToBuffer(const char *src, GWEN_BUFFER *buf)
char * GWEN_Text_Escape(const char *src, char *buffer, unsigned int maxsize)
int GWEN_Text_ToHexBuffer(const char *src, unsigned l, GWEN_BUFFER *buf, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
int GWEN_Text_DoubleToBuffer(double num, GWEN_BUFFER *buf)
int GWEN_Text_ToBcdBuffer(const char *src, unsigned l, GWEN_BUFFER *buf, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
void GWEN_Text_CondenseBuffer(GWEN_BUFFER *buf)
int GWEN_Text_EscapeToBuffer(const char *src, GWEN_BUFFER *buf)
char * GWEN_Text_UnescapeN(const char *src, unsigned int srclen, char *buffer, unsigned int maxsize)
int GWEN_Text_EscapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
static double _checkSimilarity(const char *s1, const char *s2, int ign)
int GWEN_Text_Compare(const char *s1, const char *s2, int ign)
char * GWEN_Text_UnescapeTolerant(const char *src, char *buffer, unsigned int maxsize)
int GWEN_Text_StringToDouble(const char *s, double *num)
static int _cmpSegment(const char *w, unsigned int *wpos, const char *p, unsigned int *ppos, int sensecase, unsigned int *matches)
static int _splitVariableNameInNameAndIndex(const char *s, char **pVariableName, int *pMaxLen)
int GWEN_Text_GetWordToBuffer(const char *src, const char *delims, GWEN_BUFFER *buf, uint32_t flags, const char **next)
const char * GWEN_Text_StrCaseStr(const char *haystack, const char *needle)
static int _findSegment(const char *w, unsigned int *wpos, const char *p, unsigned int *ppos, int sensecase, unsigned int *matches)
int GWEN_Text_ReplaceVars(const char *s, GWEN_BUFFER *dbuf, GWEN_TEXT_REPLACE_VARS_CB fn, void *ptr)
int GWEN_Text_EscapeXmlToBuffer(const char *src, GWEN_BUFFER *buf)
int GWEN_Text_EscapeToBufferTolerant2(GWEN_BUFFER *src, GWEN_BUFFER *buf)
char * GWEN_Text_Unescape(const char *src, char *buffer, unsigned int maxsize)
int GWEN_Text_UnescapeToBuffer(const char *src, GWEN_BUFFER *buf)
char * GWEN_Text_EscapeTolerant(const char *src, char *buffer, unsigned int maxsize)
char * GWEN_Text_GetWord(const char *src, const char *delims, char *buffer, unsigned int maxsize, uint32_t flags, const char **next)
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
int GWEN_Text_UnescapeToBufferTolerant(const char *src, GWEN_BUFFER *buf)
char * GWEN_Text_ToHexGrouped(const char *src, unsigned l, char *buffer, unsigned maxsize, unsigned int groupsize, char delimiter, int skipLeadingZeroes)
int GWEN_Text_CountUtf8Chars(const char *s, int len)
int GWEN_Text_FromHexBuffer(const char *src, GWEN_BUFFER *buf)
char * GWEN_Text_ToHex(const char *src, unsigned l, char *buffer, unsigned int maxsize)
static const GWEN_TEXT_ESCAPE_ENTRY gwen_text__xml_escape_chars[]
int GWEN_Text_FromBcdBuffer(const char *src, GWEN_BUFFER *buf)
void GWEN_Text_DumpString2Buffer(const char *s, unsigned int l, GWEN_BUFFER *mbuf, unsigned int insert)
void GWEN_Text_LogString(const char *s, unsigned int l, const char *logDomain, GWEN_LOGGER_LEVEL lv)
char * GWEN_Text_UnescapeTolerantN(const char *src, unsigned int srclen, char *buffer, unsigned int maxsize)
int GWEN_Text_FromHex(const char *src, char *buffer, unsigned maxsize)
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
int GWEN_Text_ConvertCharset(const char *fromCharset, const char *toCharset, const char *text, int len, GWEN_BUFFER *tbuf)
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
#define GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS
int GWENHYWFAR_CB(* GWEN_TEXT_REPLACE_VARS_CB)(void *cbPtr, const char *name, int index, int maxLen, GWEN_BUFFER *dstBuf)
#define GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS
#define GWEN_TEXT_FLAGS_DEL_QUOTES
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
#define GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS
#define GWEN_TEXT_FLAGS_NULL_IS_DELIMITER
#define GWEN_TEXT_FLAGS_NEED_DELIMITER