| 220 | } |
| 221 | |
| 222 | void parseFactor(int* parseFlagOut) |
| 223 | { |
| 224 | int parseFlags; |
| 225 | parsePrimary(&parseFlags); |
| 226 | |
| 227 | UChar32 op; |
| 228 | |
| 229 | if (!hasPatternChar() || !isRep((op = peekPatternChar()))) |
| 230 | { |
| 231 | *parseFlagOut = parseFlags; |
| 232 | return; |
| 233 | } |
| 234 | |
| 235 | if (!(parseFlags & PARSE_FLAG_NOT_EMPTY) && op != '?') |
| 236 | status_exception::raise(Arg::Gds(isc_invalid_similar_pattern)); |
| 237 | |
| 238 | fb_assert(op == '*' || op == '+' || op == '?' || op == '{'); |
| 239 | |
| 240 | if (op == '*') |
| 241 | { |
| 242 | re2PatternStr.append((flags & COMP_FLAG_PREFER_FEWER) ? "*?" : "*"); |
| 243 | *parseFlagOut = 0; |
| 244 | ++patternPos; |
| 245 | } |
| 246 | else if (op == '+') |
| 247 | { |
| 248 | re2PatternStr.append((flags & COMP_FLAG_PREFER_FEWER) ? "+?" : "+"); |
| 249 | *parseFlagOut = PARSE_FLAG_NOT_EMPTY; |
| 250 | ++patternPos; |
| 251 | } |
| 252 | else if (op == '?') |
| 253 | { |
| 254 | re2PatternStr.append((flags & COMP_FLAG_PREFER_FEWER) ? "??" : "?"); |
| 255 | *parseFlagOut = 0; |
| 256 | ++patternPos; |
| 257 | } |
| 258 | else if (op == '{') |
| 259 | { |
| 260 | const auto repeatStart = patternPos++; |
| 261 | |
| 262 | bool comma = false; |
| 263 | string s1, s2; |
| 264 | |
| 265 | while (true) |
| 266 | { |
| 267 | if (!hasPatternChar()) |
| 268 | status_exception::raise(Arg::Gds(isc_invalid_similar_pattern)); |
| 269 | |
| 270 | UChar32 c = getPatternChar(); |
| 271 | |
| 272 | if (c == '}') |
| 273 | { |
| 274 | if (s1.isEmpty()) |
| 275 | status_exception::raise(Arg::Gds(isc_invalid_similar_pattern)); |
| 276 | break; |
| 277 | } |
| 278 | else if (c == ',') |
| 279 | { |