diff options
Diffstat (limited to 'strings')
-rw-r--r-- | strings/Makefile.am | 8 | ||||
-rw-r--r-- | strings/ctype-big5.c | 3 | ||||
-rw-r--r-- | strings/ctype-bin.c | 7 | ||||
-rw-r--r-- | strings/ctype-czech.c | 1 | ||||
-rw-r--r-- | strings/ctype-euc_kr.c | 5 | ||||
-rw-r--r-- | strings/ctype-gb2312.c | 3 | ||||
-rw-r--r-- | strings/ctype-gbk.c | 3 | ||||
-rw-r--r-- | strings/ctype-latin1_de.c | 1 | ||||
-rw-r--r-- | strings/ctype-mb.c | 2 | ||||
-rw-r--r-- | strings/ctype-simple.c | 188 | ||||
-rw-r--r-- | strings/ctype-sjis.c | 3 | ||||
-rw-r--r-- | strings/ctype-tis620.c | 3 | ||||
-rw-r--r-- | strings/ctype-ujis.c | 3 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 38 | ||||
-rw-r--r-- | strings/ctype-win1250ch.c | 3 | ||||
-rw-r--r-- | strings/ctype.c | 257 | ||||
-rw-r--r-- | strings/my_vsnprintf.c | 166 | ||||
-rw-r--r-- | strings/xml.c | 374 |
18 files changed, 913 insertions, 155 deletions
diff --git a/strings/Makefile.am b/strings/Makefile.am index ac0b6d7f1e0..dea9effdfeb 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c xml.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c xml.c else #no assembler ASRCS = # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile -CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c +CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c xml.c endif endif @@ -44,7 +44,7 @@ noinst_PROGRAMS = conf_to_src EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ ctype-tis620.c ctype-ujis.c ctype-latin1_de.c \ - strto.c strings-x86.s \ + xml.c strto.c strings-x86.s \ longlong2str.c longlong2str-x86.s \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ strfill.c strcend.c is_prefix.c strstr.c strinstr.c \ diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 573c3c67db0..408c7f8fe35 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6218,7 +6218,8 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_big5 = { 1, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "big5", /* cs name */ "big5", /* name */ "", /* comment */ ctype_big5, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 7848862a0db..e20afff1470 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -47,8 +47,8 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), const uchar *s, uint slen, const uchar *t, uint tlen) { - int len = ( slen > tlen ) ? tlen : slen; - return memcmp(s,t,len); + int cmp= memcmp(s,t,min(slen,tlen)); + return cmp ? cmp : (int) (slen - tlen); } static void my_caseup_str_bin(CHARSET_INFO *cs __attribute__((unused)), @@ -259,7 +259,8 @@ static int my_wildcmp_bin(CHARSET_INFO *cs, static CHARSET_INFO my_charset_bin_st = { 63, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT,/* state */ + MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */ + "binary", /* cs name */ "binary", /* name */ "", /* comment */ ctype_bin, /* ctype */ diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index d309ddc80c8..bb0afe98032 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -597,6 +597,7 @@ CHARSET_INFO my_charset_czech = { 2, /* number */ MY_CS_COMPILED, /* state */ + "latin2", /* cs name */ "czech", /* name */ "", /* comment */ ctype_czech, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 2fe8db85369..814f43166c4 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8636,8 +8636,9 @@ my_mb_wc_euc_kr(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_euc_kr = { 19, /* number */ - MY_CS_COMPILED, /* state */ - "euc_kr", /* name */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "euckr", /* cs name */ + "euckr", /* name */ "", /* comment */ ctype_euc_kr, to_lower_euc_kr, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index c06b70011df..d575e48a59a 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5686,7 +5686,8 @@ my_mb_wc_gb2312(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_gb2312 = { 24, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "gb2312", /* cs name */ "gb2312", /* name */ "", /* comment */ ctype_gb2312, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 82a75188c24..0094a93e5f8 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9873,7 +9873,8 @@ my_mb_wc_gbk(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_gbk = { 28, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "gbk", /* cs name */ "gbk", /* name */ "", /* comment */ ctype_gbk, diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 49acd3fa8a8..166e059ef42 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -415,6 +415,7 @@ CHARSET_INFO my_charset_latin1_de = { 31, /* number */ MY_CS_COMPILED, /* state */ + "latin1", /* cs name */ "latin1_de", /* name */ "", /* comment */ ctype_latin1_de, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 092b7aa4f0f..5b963e74db9 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -201,7 +201,7 @@ int my_wildcmp_mb(CHARSET_INFO *cs, { // Found w_many uchar cmp; const char* mb = wildstr; - int mblen; + int mblen=0; wildstr++; /* Remove any '%' and '_' from the wild search string */ diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index fa1ece20b3e..9bcafa9f164 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -110,88 +110,40 @@ int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc, } int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, - unsigned char *s, - unsigned char *e __attribute__((unused))) + unsigned char *str, + unsigned char *end __attribute__((unused))) { MY_UNI_IDX *idx; - for(idx=cs->tab_from_uni; idx->tab ; idx++){ - if(idx->from<=wc && idx->to>=wc){ - s[0]=idx->tab[wc-idx->from]; - return (!s[0] && wc) ? MY_CS_ILUNI : 1; + for (idx=cs->tab_from_uni; idx->tab ; idx++) + { + if (idx->from <= wc && idx->to >= wc) + { + str[0]= idx->tab[wc - idx->from]; + return (!str[0] && wc) ? MY_CS_ILUNI : 1; } } return MY_CS_ILUNI; } -#ifdef NOT_USED -static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap) -{ - char *start=to, *end=to+n-1; - for (; *fmt ; fmt++) - { - if (fmt[0] != '%') - { - if (to == end) /* End of buffer */ - break; - *to++= *fmt; /* Copy ordinary char */ - continue; - } - /* Skip if max size is used (to be compatible with printf) */ - fmt++; - while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-') - fmt++; - if (*fmt == 'l') - fmt++; - if (*fmt == 's') /* String parameter */ - { - reg2 char *par = va_arg(ap, char *); - uint plen,left_len = (uint)(end-to); - if (!par) par = (char*)"(null)"; - plen = (uint) strlen(par); - if (left_len <= plen) - plen = left_len - 1; - to=strnmov(to,par,plen); - continue; - } - else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ - { - register int iarg; - if ((uint) (end-to) < 16) - break; - iarg = va_arg(ap, int); - if (*fmt == 'd') - to=int10_to_str((long) iarg,to, -10); - else - to=int10_to_str((long) (uint) iarg,to,10); - continue; - } - /* We come here on '%%', unknown code or too long parameter */ - if (to == end) - break; - *to++='%'; /* % used as % or unknown code */ - } - DBUG_ASSERT(to <= end); - *to='\0'; /* End of errmessage */ - return (uint) (to - start); -} -#endif +/* + We can't use vsprintf here as it's not guaranteed to return + the length on all operating systems. + This function is also not called in a safe environment, so the + end buffer must be checked. +*/ int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)), char* to, uint n __attribute__((unused)), const char* fmt, ...) { va_list args; + int result; va_start(args,fmt); -#ifdef NOT_USED - return my_vsnprintf_8bit(to, n, fmt, args); -#endif - /* - FIXME: generally not safe, but it is OK for now - FIXME: as far as it's not called unsafely in the current code - */ - return vsprintf(to,fmt,args); /* FIXME */ + result= my_vsnprintf(to, n, fmt, args); + va_end(args); + return result; } @@ -432,7 +384,7 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, c -= '0'; else if (c>='A' && c<='F') c = c - 'A' + 10; - else if (c>='a' && c<='a') + else if (c>='a' && c<='f') c = c - 'a' + 10; else break; @@ -690,28 +642,48 @@ noconv: return 0L; } -double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e) +/* + Read double from string + + SYNOPSIS: + my_strntod_8bit() + cs Character set information + str String to convert to double + length Optional length for string. + end pointer to end of converted string + + NOTES: + If length is not INT_MAX32 or str[length] != 0 then the given str must + be writeable + If length == INT_MAX32 the str must be \0 terminated. + + It's implemented this way to save a buffer allocation and a memory copy. + + RETURN + value of number in string +*/ + + +double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), + char *str, uint length, char **end) { - char buf[256]; - double res; - if((l+1)>sizeof(buf)) - { - if (e) - memcpy(*e,s,sizeof(s)); - return 0; - } - strncpy(buf,s,l); - buf[l]='\0'; - res=strtod(buf,e); - if (e) - memcpy(*e,*e-buf+s,sizeof(s)); - return res; + char end_char; + double result; + + if (length == INT_MAX32 || str[length] == 0) + return strtod(str, end); + end_char= str[length]; + str[length]= 0; + result= strtod(str, end); + str[length]= end_char; /* Restore end char */ + return result; } /* This is a fast version optimized for the case of radix 10 / -10 + + Assume len >= 1 */ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), @@ -720,18 +692,19 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), char buffer[66]; register char *p, *e; long int new_val; - int sl=0; - uint l; - + uint sign=0; + e = p = &buffer[sizeof(buffer)-1]; - *e='\0'; + *p= 0; if (radix < 0) { if (val < 0) { - sl = 1; - val = -val; + val= -val; + *dst++= '-'; + len--; + sign= 1; } } @@ -746,41 +719,38 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), val= new_val; } - if (sl) - { - *--p='-'; - } - - l=e-p; - l=(l>len)?len:l; - memcpy(dst,p,l); - return (int)l; + len= min(len, (uint) (e-p)); + memcpy(dst, p, len); + return (int) len+sign; } + int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), char *dst, uint len, int radix, longlong val) { char buffer[65]; register char *p, *e; long long_val; - int sl=0; - uint l; + uint sign= 0; if (radix < 0) { if (val < 0) { - sl=1; val = -val; + *dst++= '-'; + len--; + sign= 1; } } e = p = &buffer[sizeof(buffer)-1]; - *p='\0'; + *p= 0; if (val == 0) { - *--p='0'; + *--p= '0'; + len= 1; goto cnv; } @@ -800,16 +770,10 @@ int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), long_val= quo; } + len= min(len, (uint) (e-p)); cnv: - if (sl) - { - *--p='-'; - } - - l=e-p; - l=(l>len)?len:l; - memcpy(dst,p,l); - return (int)(e-p); + memcpy(dst, p, len); + return len+sign; } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 43db7ebc24a..3949be5e215 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4460,7 +4460,8 @@ my_mb_wc_sjis(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_sjis = { 13, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "sjis", /* cs name */ "sjis", /* name */ "", /* comment */ ctype_sjis, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 2dae3036426..7168026eea5 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -688,7 +688,8 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length) CHARSET_INFO my_charset_tis620 = { 18, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "tis620", /* cs name */ "tis620", /* name */ "", /* comment */ ctype_tis620, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 9d970005c85..0a0024594e4 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8430,7 +8430,8 @@ my_wc_mb_euc_jp(CHARSET_INFO *c,my_wc_t wc, unsigned char *s, unsigned char *e) CHARSET_INFO my_charset_ujis = { 12, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "ujis", /* cs name */ "ujis", /* name */ "", /* comment */ ctype_ujis, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index c32592dafec..4f72a4c2334 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1958,7 +1958,8 @@ static int my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)) , uint c) CHARSET_INFO my_charset_utf8 = { 33, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "utf8", /* cs name */ "utf8", /* name */ "", /* comment */ ctype_utf8, /* ctype */ @@ -2873,37 +2874,31 @@ bs: double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *nptr, uint l, char **endptr) + char *nptr, uint length, char **endptr) { char buf[256]; double res; register char *b=buf; register const char *s=nptr; - register const char *e=nptr+l; + register const char *end; my_wc_t wc; int cnv; - if((l+1)>sizeof(buf)) - { - if (endptr) - *endptr=(char*)nptr; - my_errno=ERANGE; - return 0; - } - - while ((cnv=cs->mb_wc(cs,&wc,s,e))>0) + /* Cut too long strings */ + if (length >= sizeof(buf)) + length= sizeof(buf)-1; + end=nptr+length; + + while ((cnv=cs->mb_wc(cs,&wc,s,end)) > 0) { s+=cnv; - if (wc < 128) - { - *b++=wc; - } - else - break; + if (wc > (int) (uchar) 'e' || !wc) + break; /* Can't be part of double */ + *b++=wc; } - *b='\0'; + *b= 0; - res=strtod(buf,endptr); + res=strtod(buf, endptr); if (endptr) *endptr=(char*) (*endptr-buf+nptr); return res; @@ -3024,7 +3019,8 @@ cnv: CHARSET_INFO my_charset_ucs2 = { 35, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "ucs2", /* cs name */ "ucs2", /* name */ "", /* comment */ ctype_ucs2, /* ctype */ diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index b7a6b21cf4a..358cede442c 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -623,7 +623,8 @@ CHARSET_INFO my_charset_win1250ch = { 34, /* number */ MY_CS_COMPILED, /* state */ - "win1250ch", /* name */ + "cp1250", /* cs name */ + "cp1250_czech", /* name */ "", /* comment */ ctype_win1250ch, to_lower_win1250ch, diff --git a/strings/ctype.c b/strings/ctype.c index 8e7d8ad939c..c2a7e928493 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -16,6 +16,7 @@ #include <my_global.h> #include <m_ctype.h> +#include <my_xml.h> #ifndef SCO #include <m_string.h> #endif @@ -2810,7 +2811,8 @@ static CHARSET_INFO compiled_charsets[] = { #ifdef HAVE_CHARSET_latin1 { 8, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + "latin1", /* cs name */ "latin1", /* name */ "", /* comment */ ctype_latin1, @@ -2856,6 +2858,7 @@ static CHARSET_INFO compiled_charsets[] = { { 14, /* number */ MY_CS_COMPILED, /* state */ + "cp1251", /* cs name */ "cp1251", /* name */ "", /* comment */ ctype_cp1251, @@ -2900,6 +2903,7 @@ static CHARSET_INFO compiled_charsets[] = { { 29, /* number */ MY_CS_COMPILED, /* state */ + "cp1257", /* cs name */ "cp1257", /* name */ "", /* comment */ ctype_cp1257, @@ -2944,6 +2948,7 @@ static CHARSET_INFO compiled_charsets[] = { { 27, /* number */ MY_CS_COMPILED, /* state */ + "latin2", /* cs name */ "croat", /* name */ "", /* comment */ ctype_croat, @@ -2989,6 +2994,7 @@ static CHARSET_INFO compiled_charsets[] = { { 15, /* number */ MY_CS_COMPILED, /* state */ + "latin1", /* cs name */ "danish", /* name */ "", /* comment */ ctype_danish, @@ -3033,6 +3039,7 @@ static CHARSET_INFO compiled_charsets[] = { { 3, /* number */ MY_CS_COMPILED, /* state */ + "dec8", /* cs name */ "dec8", /* name */ "", /* comment */ ctype_dec8, @@ -3077,6 +3084,7 @@ static CHARSET_INFO compiled_charsets[] = { { 4, /* number */ MY_CS_COMPILED, /* state */ + "cp850", /* cs name */ "dos", /* name */ "", /* comment */ ctype_dos, @@ -3121,6 +3129,7 @@ static CHARSET_INFO compiled_charsets[] = { { 20, /* number */ MY_CS_COMPILED, /* state */ + "latin7", /* cs name */ "estonia", /* name */ "", /* comment */ ctype_estonia, @@ -3166,6 +3175,7 @@ static CHARSET_INFO compiled_charsets[] = { { 5, /* number */ MY_CS_COMPILED, /* state */ + "latin1", /* cs name */ "german1", /* name */ "", /* comment */ ctype_german1, @@ -3210,6 +3220,7 @@ static CHARSET_INFO compiled_charsets[] = { { 25, /* number */ MY_CS_COMPILED, /* state */ + "greek", /* cs name */ "greek", /* name */ "", /* comment */ ctype_greek, @@ -3254,6 +3265,7 @@ static CHARSET_INFO compiled_charsets[] = { { 16, /* number */ MY_CS_COMPILED, /* state */ + "hebrew", /* cs name */ "hebrew", /* name */ "", /* comment */ ctype_hebrew, @@ -3298,6 +3310,7 @@ static CHARSET_INFO compiled_charsets[] = { { 6, /* number */ MY_CS_COMPILED, /* state */ + "hp8", /* cs name */ "hp8", /* name */ "", /* comment */ ctype_hp8, @@ -3342,6 +3355,7 @@ static CHARSET_INFO compiled_charsets[] = { { 21, /* number */ MY_CS_COMPILED, /* state */ + "latin2", /* cs name */ "hungarian", /* name */ "", /* comment */ ctype_hungarian, @@ -3386,7 +3400,8 @@ static CHARSET_INFO compiled_charsets[] = { { 7, /* number */ MY_CS_COMPILED, /* state */ - "koi8_ru", /* name */ + "koi8r", /* cs name */ + "koi8r", /* name */ "", /* comment */ ctype_koi8_ru, to_lower_koi8_ru, @@ -3430,7 +3445,8 @@ static CHARSET_INFO compiled_charsets[] = { { 22, /* number */ MY_CS_COMPILED, /* state */ - "koi8_ukr", /* name */ + "koi8u", /* cs name */ + "koi8u", /* name */ "", /* comment */ ctype_koi8_ukr, to_lower_koi8_ukr, @@ -3475,6 +3491,7 @@ static CHARSET_INFO compiled_charsets[] = { { 9, /* number */ MY_CS_COMPILED, /* state */ + "latin2", /* cs name */ "latin2", /* name */ "", /* comment */ ctype_latin2, @@ -3519,6 +3536,7 @@ static CHARSET_INFO compiled_charsets[] = { { 30, /* number */ MY_CS_COMPILED, /* state */ + "latin5", /* cs name */ "latin5", /* name */ "", /* comment */ ctype_latin5, @@ -3564,6 +3582,7 @@ static CHARSET_INFO compiled_charsets[] = { { 10, /* number */ MY_CS_COMPILED, /* state */ + "swe7", /* cs name */ "swe7", /* name */ "", /* comment */ ctype_swe7, @@ -3609,7 +3628,8 @@ static CHARSET_INFO compiled_charsets[] = { { 11, /* number */ MY_CS_COMPILED, /* state */ - "usa7", /* name */ + "ascii", /* cs name */ + "ascii", /* name */ "", /* comment */ ctype_usa7, to_lower_usa7, @@ -3653,7 +3673,8 @@ static CHARSET_INFO compiled_charsets[] = { { 26, /* number */ MY_CS_COMPILED, /* state */ - "win1250", /* name */ + "cp1250", /* cs name */ + "cp1250", /* name */ "", /* comment */ ctype_win1250, to_lower_win1250, @@ -3697,6 +3718,7 @@ static CHARSET_INFO compiled_charsets[] = { { 23, /* number */ MY_CS_COMPILED, /* state */ + "cp1251", /* cs name */ "win1251ukr", /* name */ "", /* comment */ ctype_win1251ukr, @@ -3741,6 +3763,7 @@ static CHARSET_INFO compiled_charsets[] = { { 32, /* number */ MY_CS_COMPILED, /* state */ + "armscii8", /* cs name */ "armscii8", /* name */ "", /* comment */ ctype_armscii8, @@ -3785,6 +3808,7 @@ static CHARSET_INFO compiled_charsets[] = { { 17, /* number */ MY_CS_COMPILED, /* state */ + "cp1251", /* cs name */ "win1251", /* name */ "", /* comment */ ctype_win1251, @@ -3828,6 +3852,7 @@ static CHARSET_INFO compiled_charsets[] = { { 0, /* end-of-list marker */ 0, /* state */ + NullS, /* cs name */ NullS, /* name */ NullS, /* comment */ NULL, @@ -3871,6 +3896,228 @@ static CHARSET_INFO compiled_charsets[] = { }; +static char *mstr(char *str,const char *src,uint l1,uint l2) +{ + l1= l1<l2 ? l1 : l2; + memcpy(str,src,l1); + str[l1]='\0'; + return str; +} + + +struct my_cs_file_section_st +{ + int state; + const char *str; +}; + +#define _CS_MISC 1 +#define _CS_ID 2 +#define _CS_CSNAME 3 +#define _CS_FAMILY 4 +#define _CS_ORDER 5 +#define _CS_COLNAME 6 +#define _CS_FLAG 7 +#define _CS_CHARSET 8 +#define _CS_COLLATION 9 +#define _CS_UPPERMAP 10 +#define _CS_LOWERMAP 11 +#define _CS_UNIMAP 12 +#define _CS_COLLMAP 13 +#define _CS_CTYPEMAP 14 + +static struct my_cs_file_section_st sec[] = +{ + {_CS_MISC, "xml"}, + {_CS_MISC, "xml.version"}, + {_CS_MISC, "xml.encoding"}, + {_CS_MISC, "charsets"}, + {_CS_MISC, "charsets.max-id"}, + {_CS_MISC, "charsets.description"}, + {_CS_CHARSET, "charsets.charset"}, + {_CS_CSNAME, "charsets.charset.name"}, + {_CS_FAMILY, "charsets.charset.family"}, + {_CS_MISC, "charsets.charset.alias"}, + {_CS_MISC, "charsets.charset.ctype"}, + {_CS_CTYPEMAP, "charsets.charset.ctype.map"}, + {_CS_MISC, "charsets.charset.upper"}, + {_CS_UPPERMAP, "charsets.charset.upper.map"}, + {_CS_MISC, "charsets.charset.lower"}, + {_CS_LOWERMAP, "charsets.charset.lower.map"}, + {_CS_MISC, "charsets.charset.unicode"}, + {_CS_UNIMAP, "charsets.charset.unicode.map"}, + {_CS_COLLATION, "charsets.charset.collation"}, + {_CS_COLNAME, "charsets.charset.collation.name"}, + {_CS_ID, "charsets.charset.collation.id"}, + {_CS_ORDER, "charsets.charset.collation.order"}, + {_CS_FLAG, "charsets.charset.collation.flag"}, + {_CS_COLLMAP, "charsets.charset.collation.map"}, + {0, NULL} +}; + +static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len) +{ + struct my_cs_file_section_st *s; + for (s=sec; s->str; s++) + { + if (!strncmp(attr,s->str,len)) + return s; + } + return NULL; +} + +typedef struct my_cs_file_info +{ + char csname[MY_CS_NAME_SIZE]; + char name[MY_CS_NAME_SIZE]; + uchar ctype[MY_CS_CTYPE_TABLE_SIZE]; + uchar to_lower[MY_CS_TO_LOWER_TABLE_SIZE]; + uchar to_upper[MY_CS_TO_UPPER_TABLE_SIZE]; + uchar sort_order[MY_CS_SORT_ORDER_TABLE_SIZE]; + uint16 tab_to_uni[MY_CS_TO_UNI_TABLE_SIZE]; + CHARSET_INFO cs; + int (*add_collation)(CHARSET_INFO *cs); +} MY_CHARSET_LOADER; + + + +static int fill_uchar(uchar *a,uint size,const char *str, uint len) +{ + uint i= 0; + const char *s, *b, *e=str+len; + + for (s=str ; s < e ; i++) + { + for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ; + b=s; + for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ; + if (s == b || i > size) + break; + a[i]= my_strntoul(my_charset_latin1,b,s-b,NULL,16); + } + return 0; +} + +static int fill_uint16(uint16 *a,uint size,const char *str, uint len) +{ + uint i= 0; + const char *s, *b, *e=str+len; + for (s=str ; s < e ; i++) + { + for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ; + b=s; + for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ; + if (s == b || i > size) + break; + a[i]= my_strntol(my_charset_latin1,b,s-b,NULL,16); + } + return 0; +} + + +static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len) +{ + struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; + struct my_cs_file_section_st *s= cs_file_sec(attr,len); + + if ( s && (s->state == _CS_CHARSET)) + { + bzero(&i->cs,sizeof(i->cs)); + } + return MY_XML_OK; +} + + +static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len) +{ + struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; + struct my_cs_file_section_st *s= cs_file_sec(attr,len); + int state= s ? s->state : 0; + int rc; + + switch(state){ + case _CS_COLLATION: + rc= i->add_collation ? i->add_collation(&i->cs) : MY_XML_OK; + break; + default: + rc=MY_XML_OK; + } + return rc; +} + + +static int cs_value(MY_XML_PARSER *st,const char *attr, uint len) +{ + struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; + struct my_cs_file_section_st *s; + int state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0; + +#ifndef DBUG_OFF + if(0){ + char str[1024]; + mstr(str,attr,len,sizeof(str)-1); + printf("VALUE %d %s='%s'\n",state,st->attr,str); + } +#endif + + switch (state) { + case _CS_ID: + i->cs.number= my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0); + break; + case _CS_COLNAME: + i->cs.name=mstr(i->name,attr,len,MY_CS_NAME_SIZE-1); + break; + case _CS_CSNAME: + i->cs.csname=mstr(i->csname,attr,len,MY_CS_NAME_SIZE-1); + break; + case _CS_FLAG: + if (!strncmp("primary",attr,len)) + i->cs.state|= MY_CS_PRIMARY; + break; + case _CS_UPPERMAP: + fill_uchar(i->to_upper,MY_CS_TO_UPPER_TABLE_SIZE,attr,len); + i->cs.to_upper=i->to_upper; + break; + case _CS_LOWERMAP: + fill_uchar(i->to_lower,MY_CS_TO_LOWER_TABLE_SIZE,attr,len); + i->cs.to_lower=i->to_lower; + break; + case _CS_UNIMAP: + fill_uint16(i->tab_to_uni,MY_CS_TO_UNI_TABLE_SIZE,attr,len); + i->cs.tab_to_uni=i->tab_to_uni; + break; + case _CS_COLLMAP: + fill_uchar(i->sort_order,MY_CS_SORT_ORDER_TABLE_SIZE,attr,len); + i->cs.sort_order=i->sort_order; + break; + case _CS_CTYPEMAP: + fill_uchar(i->ctype,MY_CS_CTYPE_TABLE_SIZE,attr,len); + i->cs.ctype=i->ctype; + break; + } + return MY_XML_OK; +} + + +my_bool my_parse_charset_xml(const char *buf, uint len, + int (*add_collation)(CHARSET_INFO *cs)) +{ + MY_XML_PARSER p; + struct my_cs_file_info i; + my_bool rc; + + my_xml_parser_create(&p); + my_xml_set_enter_handler(&p,cs_enter); + my_xml_set_value_handler(&p,cs_value); + my_xml_set_leave_handler(&p,cs_leave); + i.add_collation= add_collation; + my_xml_set_user_data(&p,(void*)&i); + rc= (my_xml_parse(&p,buf,len) == MY_XML_OK) ? FALSE : TRUE; + my_xml_parser_free(&p); + return rc; +} + + CHARSET_INFO *my_charset_latin1 = &compiled_charsets[0]; CHARSET_INFO *all_charsets[256]; CHARSET_INFO *default_charset_info = &compiled_charsets[0]; diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c new file mode 100644 index 00000000000..a67523af7bc --- /dev/null +++ b/strings/my_vsnprintf.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2000 MySQL AB + + 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <my_global.h> +#include <m_string.h> +#include <stdarg.h> +#include <m_ctype.h> +#include <assert.h> + +/* + Limited snprintf() implementations + + IMPLEMENTION: + Supports following formats: + %#d + %#u + %#.#s Note #.# is skiped + + RETURN + length of result string +*/ + +int my_snprintf(char* to, size_t n, const char* fmt, ...) +{ + va_list args; + int result; + va_start(args,fmt); + result= my_vsnprintf(to, n, fmt, args); + va_end(args); + return result; +} + + +int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) +{ + char *start=to, *end=to+n-1; + uint length, num_state, pre_zero; + + for (; *fmt ; fmt++) + { + if (fmt[0] != '%') + { + if (to == end) /* End of buffer */ + break; + *to++= *fmt; /* Copy ordinary char */ + continue; + } + fmt++; /* skip '%' */ + /* Read max fill size (only used with %d and %u) */ + if (*fmt == '-') + fmt++; + length= num_state= pre_zero= 0; + for (;; fmt++) + { + if (my_isdigit(system_charset_info,*fmt)) + { + if (!num_state) + { + length=length*10+ (uint) (*fmt-'0'); + if (!length) + pre_zero= 1; /* first digit was 0 */ + } + continue; + } + if (*fmt != '.' || num_state) + break; + num_state= 1; + } + if (*fmt == 'l') + fmt++; + if (*fmt == 's') /* String parameter */ + { + reg2 char *par = va_arg(ap, char *); + uint plen,left_len = (uint)(end-to); + if (!par) par = (char*)"(null)"; + plen = (uint) strlen(par); + if (left_len <= plen) + plen = left_len - 1; + to=strnmov(to,par,plen); + continue; + } + else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ + { + register int iarg; + char *to_start= to; + if ((uint) (end-to) < max(16,length)) + break; + iarg = va_arg(ap, int); + if (*fmt == 'd') + to=int10_to_str((long) iarg,to, -10); + else + to=int10_to_str((long) (uint) iarg,to,10); + /* If %#d syntax was used, we have to pre-zero/pre-space the string */ + if (length) + { + uint res_length= (uint) (to - to_start); + if (res_length < length) + { + uint diff= (length- res_length); + bmove_upp(to+diff, to, res_length); + bfill(to-res_length, diff, pre_zero ? '0' : ' '); + to+= diff; + } + } + continue; + } + /* We come here on '%%', unknown code or too long parameter */ + if (to == end) + break; + *to++='%'; /* % used as % or unknown code */ + } + DBUG_ASSERT(to <= end); + *to='\0'; /* End of errmessage */ + return (uint) (to - start); +} + +#ifdef MAIN +#define OVERRUN_SENTRY 250 +static void my_printf(const char * fmt, ...) +{ + char buf[33]; + int n; + va_list ar; + va_start(ar, fmt); + buf[sizeof(buf)-1]=OVERRUN_SENTRY; + n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar); + printf(buf); + printf("n=%d, strlen=%d\n", n, strlen(buf)); + if (buf[sizeof(buf)-1] != OVERRUN_SENTRY) + { + fprintf(stderr, "Buffer overrun\n"); + abort(); + } + va_end(ar); +} + +int main() +{ + + my_printf("Hello\n"); + my_printf("Hello int, %d\n", 1); + my_printf("Hello string '%s'\n", "I am a string"); + my_printf("Hello hack hack hack hack hack hack hack %d\n", 1); + my_printf("Hello %d hack %d\n", 1, 4); + my_printf("Hello %d hack hack hack hack hack %d\n", 1, 4); + my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack"); + my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1); + my_printf("Hello %u\n", 1); + my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\ + `%-.64s' (%-.64s)", 1, 0,0,0,0); + return 0; +} +#endif diff --git a/strings/xml.c b/strings/xml.c new file mode 100644 index 00000000000..4f6301249ae --- /dev/null +++ b/strings/xml.c @@ -0,0 +1,374 @@ +/* Copyright (C) 2000 MySQL AB + + 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "my_global.h" +#include "m_string.h" +#include "my_xml.h" + + +#define MY_XML_EOF 'E' +#define MY_XML_STRING 'S' +#define MY_XML_IDENT 'I' +#define MY_XML_EQ '=' +#define MY_XML_LT '<' +#define MY_XML_GT '>' +#define MY_XML_SLASH '/' +#define MY_XML_COMMENT 'C' +#define MY_XML_TEXT 'T' +#define MY_XML_QUESTION '?' +#define MY_XML_EXCLAM '!' + +typedef struct xml_attr_st +{ + const char *beg; + const char *end; +} MY_XML_ATTR; + +static const char *lex2str(int lex) +{ + switch(lex) + { + case MY_XML_EOF: return "EOF"; + case MY_XML_STRING: return "STRING"; + case MY_XML_IDENT: return "IDENT"; + case MY_XML_EQ: return "'='"; + case MY_XML_LT: return "'<'"; + case MY_XML_GT: return "'>'"; + case MY_XML_SLASH: return "'/'"; + case MY_XML_COMMENT: return "COMMENT"; + case MY_XML_TEXT: return "TEXT"; + case MY_XML_QUESTION: return "'?'"; + case MY_XML_EXCLAM: return "'!'"; + } + return "UNKNOWN"; +} + +static void my_xml_norm_text(MY_XML_ATTR *a) +{ + for ( ; (a->beg < a->end) && strchr(" \t\r\n",a->beg[0]) ; a->beg++ ); + for ( ; (a->beg < a->end) && strchr(" \t\r\n",a->end[-1]) ; a->end-- ); +} + + +static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) +{ + int lex; + + for( ; ( p->cur < p->end) && strchr(" \t\r\n",p->cur[0]) ; p->cur++); + + if (p->cur >= p->end) + { + a->beg=p->end; + a->end=p->end; + lex=MY_XML_EOF; + goto ret; + } + + a->beg=p->cur; + a->end=p->cur; + + if (!memcmp(p->cur,"<!--",4)) + { + for( ; (p->cur < p->end) && memcmp(p->cur, "-->", 3); p->cur++); + if(!memcmp(p->cur, "-->", 3)) + p->cur+=3; + a->end=p->cur; + lex=MY_XML_COMMENT; + } + else if (strchr("?=/<>!",p->cur[0])) + { + p->cur++; + a->end=p->cur; + lex=a->beg[0]; + } + else if ( (p->cur[0]=='"') || (p->cur[0]=='\'') ) + { + p->cur++; + for( ; ( p->cur < p->end ) && (p->cur[0]!=a->beg[0]); p->cur++); + a->end=p->cur; + if (a->beg[0]==p->cur[0])p->cur++; + a->beg++; + my_xml_norm_text(a); + lex=MY_XML_STRING; + } + else + { + for( ; (p->cur < p->end) && !strchr("?'\"=/<> \t\r\n", p->cur[0]); p->cur++); + a->end=p->cur; + my_xml_norm_text(a); + lex=MY_XML_IDENT; + } + +#if 0 + printf("LEX=%s[%d]\n",lex2str(lex),a->end-a->beg); +#endif + +ret: + return lex; +} + + +static int my_xml_value(MY_XML_PARSER *st, const char *str, uint len) +{ + return (st->value) ? (st->value)(st,str,len) : MY_XML_OK; +} + + +static int my_xml_enter(MY_XML_PARSER *st, const char *str, uint len) +{ + if ( (st->attrend-st->attr+len+1)>sizeof(st->attr)) + { + sprintf(st->errstr,"To deep XML"); + return MY_XML_ERROR; + } + if (st->attrend > st->attr) + { + st->attrend[0]='.'; + st->attrend++; + } + memcpy(st->attrend,str,len); + st->attrend+=len; + st->attrend[0]='\0'; + return st->enter ? st->enter(st,st->attr,st->attrend-st->attr) : MY_XML_OK; +} + +static void mstr(char *s,const char *src,uint l1, uint l2) +{ + l1 = l1<l2 ? l1 : l2; + memcpy(s,src,l1); + s[l1]='\0'; +} + +static int my_xml_leave(MY_XML_PARSER *p, const char *str, uint slen) +{ + char *e; + uint glen; + char s[32]; + char g[32]; + int rc; + + /* Find previous '.' or beginning */ + for( e=p->attrend; (e>p->attr) && (e[0]!='.') ; e--); + glen = (e[0]=='.') ? (p->attrend-e-1) : p->attrend-e; + + if (str && (slen != glen)) + { + mstr(s,str,sizeof(s)-1,slen); + mstr(g,e+1,sizeof(g)-1,glen), + sprintf(p->errstr,"'</%s>' unexpected ('</%s>' wanted)",s,g); + return MY_XML_ERROR; + } + + rc = p->leave ? p->leave(p,p->attr,p->attrend-p->attr) : MY_XML_OK; + + *e='\0'; + p->attrend=e; + + return rc; +} + + +int my_xml_parse(MY_XML_PARSER *p,const char *str, uint len) +{ + p->attrend=p->attr; + p->beg=str; + p->cur=str; + p->end=str+len; + + while ( p->cur < p->end ) + { + MY_XML_ATTR a; + if(p->cur[0]=='<') + { + int lex; + int question=0; + int exclam=0; + + lex=my_xml_scan(p,&a); + + if (MY_XML_COMMENT==lex) + { + continue; + } + + lex=my_xml_scan(p,&a); + + if (MY_XML_SLASH==lex) + { + if(MY_XML_IDENT!=(lex=my_xml_scan(p,&a))) + { + sprintf(p->errstr,"1: %s unexpected (ident wanted)",lex2str(lex)); + return MY_XML_ERROR; + } + if(MY_XML_OK!=my_xml_leave(p,a.beg,a.end-a.beg)) + return MY_XML_ERROR; + lex=my_xml_scan(p,&a); + goto gt; + } + + if (MY_XML_EXCLAM==lex) + { + lex=my_xml_scan(p,&a); + exclam=1; + } + else if (MY_XML_QUESTION==lex) + { + lex=my_xml_scan(p,&a); + question=1; + } + + if (MY_XML_IDENT==lex) + { + if(MY_XML_OK!=my_xml_enter(p,a.beg,a.end-a.beg)) + return MY_XML_ERROR; + } + else + { + sprintf(p->errstr,"3: %s unexpected (ident or '/' wanted)",lex2str(lex)); + return MY_XML_ERROR; + } + + while ((MY_XML_IDENT==(lex=my_xml_scan(p,&a))) || (MY_XML_STRING==lex)) + { + MY_XML_ATTR b; + if(MY_XML_EQ==(lex=my_xml_scan(p,&b))) + { + lex=my_xml_scan(p,&b); + if ( (lex==MY_XML_IDENT) || (lex=MY_XML_STRING) ) + { + if((MY_XML_OK!=my_xml_enter(p,a.beg,a.end-a.beg)) || + (MY_XML_OK!=my_xml_value(p,b.beg,b.end-b.beg)) || + (MY_XML_OK!=my_xml_leave(p,a.beg,a.end-a.beg))) + return MY_XML_ERROR; + } + else + { + sprintf(p->errstr,"4: %s unexpected (ident or string wanted)",lex2str(lex)); + return MY_XML_ERROR; + } + } + else if ( (MY_XML_STRING==lex) || (MY_XML_IDENT==lex) ) + { + if((MY_XML_OK!=my_xml_enter(p,a.beg,a.end-a.beg)) || + (MY_XML_OK!=my_xml_leave(p,a.beg,a.end-a.beg))) + return MY_XML_ERROR; + } + else + break; + } + + if (lex==MY_XML_SLASH) + { + if(MY_XML_OK!=my_xml_leave(p,NULL,0)) + return MY_XML_ERROR; + lex=my_xml_scan(p,&a); + } + +gt: + if (question) + { + if (lex!=MY_XML_QUESTION) + { + sprintf(p->errstr,"6: %s unexpected ('?' wanted)",lex2str(lex)); + return MY_XML_ERROR; + } + if(MY_XML_OK!=my_xml_leave(p,NULL,0)) + return MY_XML_ERROR; + lex=my_xml_scan(p,&a); + } + + if (exclam) + { + if(MY_XML_OK!=my_xml_leave(p,NULL,0)) + return MY_XML_ERROR; + } + + if (lex!=MY_XML_GT) + { + sprintf(p->errstr,"5: %s unexpected ('>' wanted)",lex2str(lex)); + return MY_XML_ERROR; + } + } + else + { + a.beg=p->cur; + for ( ; (p->cur < p->end) && (p->cur[0]!='<') ; p->cur++); + a.end=p->cur; + + my_xml_norm_text(&a); + if (a.beg!=a.end) + { + my_xml_value(p,a.beg,a.end-a.beg); + } + } + } + return MY_XML_OK; +} + +void my_xml_parser_create(MY_XML_PARSER *p) +{ + bzero((void*)p,sizeof(p[0])); +} + +void my_xml_parser_free(MY_XML_PARSER *p __attribute__((unused))) +{ +} + +void my_xml_set_value_handler(MY_XML_PARSER *p, int (*action)(MY_XML_PARSER *p, const char *s, uint l)) +{ + p->value=action; +} + +void my_xml_set_enter_handler(MY_XML_PARSER *p, int (*action)(MY_XML_PARSER *p, const char *s, uint l)) +{ + p->enter=action; +} + +void my_xml_set_leave_handler(MY_XML_PARSER *p, int (*action)(MY_XML_PARSER *p, const char *s, uint l)) +{ + p->leave=action; +} + +void my_xml_set_user_data(MY_XML_PARSER *p, void *user_data) +{ + p->user_data=user_data; +} + +const char *my_xml_error_string(MY_XML_PARSER *p) +{ + return p->errstr; +} + + +uint my_xml_error_pos(MY_XML_PARSER *p) +{ + const char *beg=p->beg; + const char *s; + for ( s=p->beg ; s<p->cur; s++) + if (s[0]=='\n') + beg=s; + return p->cur-beg; +} + +uint my_xml_error_lineno(MY_XML_PARSER *p) +{ + uint res=0; + const char *s; + for ( s=p->beg ; s<p->cur; s++) + if (s[0]=='\n') + res++; + return res; +} |