1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (c) 2001-2011, International Business Machines 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11/19/2001 aliu Creation. 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h" 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "util.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse an integer at pos, either of the form \d+ or of the form 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 0x[0-9A-Fa-f]+ or 0[0-7]+, that is, in standard decimal, hex, 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * or octal format. 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pos INPUT-OUTPUT parameter. On input, the first 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * character to parse. On output, the character after the last 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * parsed character. 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t ICU_Utility::parseInteger(const UnicodeString& rule, int32_t& pos, int32_t limit) { 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t count = 0; 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t value = 0; 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t p = pos; 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t radix = 10; 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p < limit && rule.charAt(p) == 48 /*0*/) { 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p+1 < limit && (rule.charAt(p+1) == 0x78 /*x*/ || rule.charAt(p+1) == 0x58 /*X*/)) { 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p += 2; 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru radix = 16; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p++; 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = 1; 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru radix = 8; 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p < limit) { 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t d = u_digit(rule.charAt(p++), radix); 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (d < 0) { 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --p; 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++count; 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t v = (value * radix) + d; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (v <= value) { 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // If there are too many input digits, at some point 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the value will go negative, e.g., if we have seen 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // "0x8000000" already and there is another '0', when 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we parse the next 0 the value will go negative. 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value = v; 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (count > 0) { 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = p; 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return value; 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse a pattern string starting at offset pos. Keywords are 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * matched case-insensitively. Spaces may be skipped and may be 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * optional or required. Integer values may be parsed, and if 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * they are, they will be returned in the given array. If 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * successful, the offset of the next non-space character is 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * returned. On failure, -1 is returned. 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pattern must only contain lowercase characters, which 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * will match their uppercase equivalents as well. A space 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * character matches one or more required spaces. A '~' character 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * matches zero or more optional spaces. A '#' character matches 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * an integer and stores it in parsedInts, which the caller must 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ensure has enough capacity. 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param parsedInts array to receive parsed integers. Caller 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * must ensure that parsedInts.length is >= the number of '#' 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * signs in 'pattern'. 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the position after the last character parsed, or -1 if 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the parse failed 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t ICU_Utility::parsePattern(const UnicodeString& rule, int32_t pos, int32_t limit, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& pattern, int32_t* parsedInts) { 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO Update this to handle surrogates 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t p; 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t intCount = 0; // number of integers parsed 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i=0; i<pattern.length(); ++i) { 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar cpat = pattern.charAt(i); 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar c; 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (cpat) { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 32 /*' '*/: 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pos >= limit) { 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c = rule.charAt(pos++); 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!PatternProps::isWhiteSpace(c)) { 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // FALL THROUGH to skipWhitespace 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 126 /*'~'*/: 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = skipWhitespace(rule, pos); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 35 /*'#'*/: 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p = pos; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru parsedInts[intCount++] = parseInteger(rule, p, limit); 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == pos) { 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Syntax error; failed to parse integer 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = p; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pos >= limit) { 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru c = (UChar) u_tolower(rule.charAt(pos++)); 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (c != cpat) { 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pos; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse a Unicode identifier from the given string at the given 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * position. Return the identifier, or an empty string if there 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is no identifier. 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param str the string to parse 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pos INPUT-OUPUT parameter. On INPUT, pos is the 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * first character to examine. It must be less than str.length(), 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and it must not point to a whitespace character. That is, must 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * have pos < str.length(). On 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * OUTPUT, the position after the last parsed character. 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the Unicode identifier, or an empty string if there is 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * no valid identifier at pos. 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString ICU_Utility::parseUnicodeIdentifier(const UnicodeString& str, int32_t& pos) { 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // assert(pos < str.length()); 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString buf; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int p = pos; 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p < str.length()) { 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 ch = str.char32At(p); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (buf.length() == 0) { 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (u_isIDStart(ch)) { 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf.append(ch); 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf.truncate(0); 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return buf; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (u_isIDPart(ch)) { 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf.append(ch); 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p += UTF_CHAR_LENGTH(ch); 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = p; 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return buf; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse an unsigned 31-bit integer at the given offset. Use 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UCharacter.digit() to parse individual characters into digits. 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param text the text to be parsed 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pos INPUT-OUTPUT parameter. On entry, pos[0] is the 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * offset within text at which to start parsing; it should point 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to a valid digit. On exit, pos[0] is the offset after the last 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * parsed character. If the parse failed, it will be unchanged on 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * exit. Must be >= 0 on entry. 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param radix the radix in which to parse; must be >= 2 and <= 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 36. 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return a non-negative parsed number, or -1 upon parse failure. 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse fails if there are no digits, that is, if pos[0] does not 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * point to a valid digit on entry, or if the number to be parsed 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * does not fit into a 31-bit unsigned integer. 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t ICU_Utility::parseNumber(const UnicodeString& text, 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t& pos, int8_t radix) { 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // assert(pos[0] >= 0); 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // assert(radix >= 2); 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // assert(radix <= 36); 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t n = 0; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t p = pos; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p < text.length()) { 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar32 ch = text.char32At(p); 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t d = u_digit(ch, radix); 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (d < 0) { 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru n = radix*n + d; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ASSUME that when a 32-bit integer overflows it becomes 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // negative. E.g., 214748364 * 10 + 8 => negative value. 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n < 0) { 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++p; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == pos) { 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos = p; 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return n; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 214