| 45 | static const char field_separator=','; |
| 46 | |
| 47 | ulonglong find_set(TYPELIB *lib, const char *str, uint length, |
| 48 | const CHARSET_INFO *cs, |
| 49 | char **err_pos, uint *err_len, bool *set_warning) |
| 50 | { |
| 51 | const CHARSET_INFO *strip= cs ? cs : &my_charset_latin1; |
| 52 | const char *end= str + strip->cset->lengthsp(strip, str, length); |
| 53 | ulonglong found= 0; |
| 54 | *err_pos= 0; // No error yet |
| 55 | *err_len= 0; |
| 56 | if (str != end) |
| 57 | { |
| 58 | const char *start= str; |
| 59 | for (;;) |
| 60 | { |
| 61 | const char *pos= start; |
| 62 | uint var_len; |
| 63 | int mblen= 1; |
| 64 | |
| 65 | if (cs && cs->mbminlen > 1) |
| 66 | { |
| 67 | for ( ; pos < end; pos+= mblen) |
| 68 | { |
| 69 | my_wc_t wc; |
| 70 | if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) pos, |
| 71 | (const uchar *) end)) < 1) |
| 72 | mblen= 1; // Not to hang on a wrong multibyte sequence |
| 73 | if (wc == (my_wc_t) field_separator) |
| 74 | break; |
| 75 | } |
| 76 | } |
| 77 | else |
| 78 | for (; pos != end && *pos != field_separator; pos++) ; |
| 79 | var_len= (uint) (pos - start); |
| 80 | uint find= cs ? find_type2(lib, start, var_len, cs) : |
| 81 | find_type(lib, start, var_len, (bool) 0); |
| 82 | if (!find && *err_len == 0) // report the first error with length > 0 |
| 83 | { |
| 84 | *err_pos= (char*) start; |
| 85 | *err_len= var_len; |
| 86 | *set_warning= 1; |
| 87 | } |
| 88 | else |
| 89 | found|= 1ULL << (find - 1); |
| 90 | if (pos >= end) |
| 91 | break; |
| 92 | start= pos + mblen; |
| 93 | } |
| 94 | } |
| 95 | return found; |
| 96 | } |
| 97 | |
| 98 | /* |
| 99 | Function to find a string in a TYPELIB |
no test coverage detected