regexec.c - Oniguruma (regular expression library)\r
**********************************************************************/\r
/*-\r
- * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>\r
+ * Copyright (c) 2002-2018 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>\r
* All rights reserved.\r
*\r
- * (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
- *\r
* Redistribution and use in source and binary forms, with or without\r
* modification, are permitted provided that the following conditions\r
* are met:\r
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
* SUCH DAMAGE.\r
*/\r
-\r
#include "regint.h"\r
\r
-#define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
+#define IS_MBC_WORD_ASCII_MODE(enc,s,end,mode) \\r
+ ((mode) == 0 ? ONIGENC_IS_MBC_WORD(enc,s,end) : ONIGENC_IS_MBC_WORD_ASCII(enc,s,end))\r
\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
#define ONIGENC_IS_MBC_CRNL(enc,p,end) \\r
ONIGENC_IS_MBC_NEWLINE(enc,(p+enclen(enc,p)),end))\r
#endif\r
\r
+#define CHECK_INTERRUPT_IN_MATCH\r
+\r
+#ifdef USE_CALLOUT\r
+typedef struct {\r
+ int last_match_at_call_counter;\r
+ struct {\r
+ OnigType type;\r
+ OnigValue val;\r
+ } slot[ONIG_CALLOUT_DATA_SLOT_NUM];\r
+} CalloutData;\r
+#endif\r
+\r
+struct OnigMatchParamStruct {\r
+ unsigned int match_stack_limit;\r
+ unsigned long retry_limit_in_match;\r
+#ifdef USE_CALLOUT\r
+ OnigCalloutFunc progress_callout_of_contents;\r
+ OnigCalloutFunc retraction_callout_of_contents;\r
+ int match_at_call_counter;\r
+ void* callout_user_data;\r
+ CalloutData* callout_data;\r
+ int callout_data_alloc_num;\r
+#endif\r
+};\r
+\r
+extern int\r
+onig_set_match_stack_limit_size_of_match_param(OnigMatchParam* param,\r
+ unsigned int limit)\r
+{\r
+ param->match_stack_limit = limit;\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern int\r
+onig_set_retry_limit_in_match_of_match_param(OnigMatchParam* param,\r
+ unsigned long limit)\r
+{\r
+ param->retry_limit_in_match = limit;\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern int\r
+onig_set_progress_callout_of_match_param(OnigMatchParam* param, OnigCalloutFunc f)\r
+{\r
+#ifdef USE_CALLOUT\r
+ param->progress_callout_of_contents = f;\r
+ return ONIG_NORMAL;\r
+#else\r
+ return ONIG_NO_SUPPORT_CONFIG;\r
+#endif\r
+}\r
+\r
+extern int\r
+onig_set_retraction_callout_of_match_param(OnigMatchParam* param, OnigCalloutFunc f)\r
+{\r
+#ifdef USE_CALLOUT\r
+ param->retraction_callout_of_contents = f;\r
+ return ONIG_NORMAL;\r
+#else\r
+ return ONIG_NO_SUPPORT_CONFIG;\r
+#endif\r
+}\r
+\r
+extern int\r
+onig_set_callout_user_data_of_match_param(OnigMatchParam* param, void* user_data)\r
+{\r
+#ifdef USE_CALLOUT\r
+ param->callout_user_data = user_data;\r
+ return ONIG_NORMAL;\r
+#else\r
+ return ONIG_NO_SUPPORT_CONFIG;\r
+#endif\r
+}\r
+\r
+\r
+\r
+typedef struct {\r
+ void* stack_p;\r
+ int stack_n;\r
+ OnigOptionType options;\r
+ OnigRegion* region;\r
+ int ptr_num;\r
+ const UChar* start; /* search start position (for \G: BEGIN_POSITION) */\r
+ unsigned int match_stack_limit;\r
+ unsigned long retry_limit_in_match;\r
+ OnigMatchParam* mp;\r
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
+ int best_len; /* for ONIG_OPTION_FIND_LONGEST */\r
+ UChar* best_s;\r
+#endif\r
+} MatchArg;\r
+\r
+\r
+#ifdef ONIG_DEBUG\r
+\r
+/* arguments type */\r
+typedef enum {\r
+ ARG_SPECIAL = -1,\r
+ ARG_NON = 0,\r
+ ARG_RELADDR = 1,\r
+ ARG_ABSADDR = 2,\r
+ ARG_LENGTH = 3,\r
+ ARG_MEMNUM = 4,\r
+ ARG_OPTION = 5,\r
+ ARG_MODE = 6\r
+} OpArgType;\r
+\r
+typedef struct {\r
+ short int opcode;\r
+ char* name;\r
+ OpArgType arg_type;\r
+} OpInfoType;\r
+\r
+static OpInfoType OpInfo[] = {\r
+ { OP_FINISH, "finish", ARG_NON },\r
+ { OP_END, "end", ARG_NON },\r
+ { OP_EXACT1, "exact1", ARG_SPECIAL },\r
+ { OP_EXACT2, "exact2", ARG_SPECIAL },\r
+ { OP_EXACT3, "exact3", ARG_SPECIAL },\r
+ { OP_EXACT4, "exact4", ARG_SPECIAL },\r
+ { OP_EXACT5, "exact5", ARG_SPECIAL },\r
+ { OP_EXACTN, "exactn", ARG_SPECIAL },\r
+ { OP_EXACTMB2N1, "exactmb2-n1", ARG_SPECIAL },\r
+ { OP_EXACTMB2N2, "exactmb2-n2", ARG_SPECIAL },\r
+ { OP_EXACTMB2N3, "exactmb2-n3", ARG_SPECIAL },\r
+ { OP_EXACTMB2N, "exactmb2-n", ARG_SPECIAL },\r
+ { OP_EXACTMB3N, "exactmb3n" , ARG_SPECIAL },\r
+ { OP_EXACTMBN, "exactmbn", ARG_SPECIAL },\r
+ { OP_EXACT1_IC, "exact1-ic", ARG_SPECIAL },\r
+ { OP_EXACTN_IC, "exactn-ic", ARG_SPECIAL },\r
+ { OP_CCLASS, "cclass", ARG_SPECIAL },\r
+ { OP_CCLASS_MB, "cclass-mb", ARG_SPECIAL },\r
+ { OP_CCLASS_MIX, "cclass-mix", ARG_SPECIAL },\r
+ { OP_CCLASS_NOT, "cclass-not", ARG_SPECIAL },\r
+ { OP_CCLASS_MB_NOT, "cclass-mb-not", ARG_SPECIAL },\r
+ { OP_CCLASS_MIX_NOT, "cclass-mix-not", ARG_SPECIAL },\r
+#ifdef USE_OP_CCLASS_NODE\r
+ { OP_CCLASS_NODE, "cclass-node", ARG_SPECIAL },\r
+#endif\r
+ { OP_ANYCHAR, "anychar", ARG_NON },\r
+ { OP_ANYCHAR_ML, "anychar-ml", ARG_NON },\r
+ { OP_ANYCHAR_STAR, "anychar*", ARG_NON },\r
+ { OP_ANYCHAR_ML_STAR, "anychar-ml*", ARG_NON },\r
+ { OP_ANYCHAR_STAR_PEEK_NEXT, "anychar*-peek-next", ARG_SPECIAL },\r
+ { OP_ANYCHAR_ML_STAR_PEEK_NEXT, "anychar-ml*-peek-next", ARG_SPECIAL },\r
+ { OP_WORD, "word", ARG_NON },\r
+ { OP_WORD_ASCII, "word-ascii", ARG_NON },\r
+ { OP_NO_WORD, "not-word", ARG_NON },\r
+ { OP_NO_WORD_ASCII, "not-word-ascii", ARG_NON },\r
+ { OP_WORD_BOUNDARY, "word-boundary", ARG_MODE },\r
+ { OP_NO_WORD_BOUNDARY, "not-word-boundary", ARG_MODE },\r
+ { OP_WORD_BEGIN, "word-begin", ARG_MODE },\r
+ { OP_WORD_END, "word-end", ARG_MODE },\r
+ { OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY, "extended-grapheme-cluster-boundary", ARG_NON },\r
+ { OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY, "no-extended-grapheme-cluster-boundary", ARG_NON },\r
+ { OP_BEGIN_BUF, "begin-buf", ARG_NON },\r
+ { OP_END_BUF, "end-buf", ARG_NON },\r
+ { OP_BEGIN_LINE, "begin-line", ARG_NON },\r
+ { OP_END_LINE, "end-line", ARG_NON },\r
+ { OP_SEMI_END_BUF, "semi-end-buf", ARG_NON },\r
+ { OP_BEGIN_POSITION, "begin-position", ARG_NON },\r
+ { OP_BACKREF1, "backref1", ARG_NON },\r
+ { OP_BACKREF2, "backref2", ARG_NON },\r
+ { OP_BACKREF_N, "backref-n", ARG_MEMNUM },\r
+ { OP_BACKREF_N_IC, "backref-n-ic", ARG_SPECIAL },\r
+ { OP_BACKREF_MULTI, "backref_multi", ARG_SPECIAL },\r
+ { OP_BACKREF_MULTI_IC, "backref_multi-ic", ARG_SPECIAL },\r
+ { OP_BACKREF_WITH_LEVEL, "backref_with_level", ARG_SPECIAL },\r
+ { OP_BACKREF_CHECK, "backref_check", ARG_SPECIAL },\r
+ { OP_BACKREF_CHECK_WITH_LEVEL, "backref_check_with_level", ARG_SPECIAL },\r
+ { OP_MEMORY_START_PUSH, "mem-start-push", ARG_MEMNUM },\r
+ { OP_MEMORY_START, "mem-start", ARG_MEMNUM },\r
+ { OP_MEMORY_END_PUSH, "mem-end-push", ARG_MEMNUM },\r
+ { OP_MEMORY_END_PUSH_REC, "mem-end-push-rec", ARG_MEMNUM },\r
+ { OP_MEMORY_END, "mem-end", ARG_MEMNUM },\r
+ { OP_MEMORY_END_REC, "mem-end-rec", ARG_MEMNUM },\r
+ { OP_FAIL, "fail", ARG_NON },\r
+ { OP_JUMP, "jump", ARG_RELADDR },\r
+ { OP_PUSH, "push", ARG_RELADDR },\r
+ { OP_PUSH_SUPER, "push-super", ARG_RELADDR },\r
+ { OP_POP_OUT, "pop-out", ARG_NON },\r
+ { OP_PUSH_OR_JUMP_EXACT1, "push-or-jump-e1", ARG_SPECIAL },\r
+ { OP_PUSH_IF_PEEK_NEXT, "push-if-peek-next", ARG_SPECIAL },\r
+ { OP_REPEAT, "repeat", ARG_SPECIAL },\r
+ { OP_REPEAT_NG, "repeat-ng", ARG_SPECIAL },\r
+ { OP_REPEAT_INC, "repeat-inc", ARG_MEMNUM },\r
+ { OP_REPEAT_INC_NG, "repeat-inc-ng", ARG_MEMNUM },\r
+ { OP_REPEAT_INC_SG, "repeat-inc-sg", ARG_MEMNUM },\r
+ { OP_REPEAT_INC_NG_SG, "repeat-inc-ng-sg", ARG_MEMNUM },\r
+ { OP_EMPTY_CHECK_START, "empty-check-start", ARG_MEMNUM },\r
+ { OP_EMPTY_CHECK_END, "empty-check-end", ARG_MEMNUM },\r
+ { OP_EMPTY_CHECK_END_MEMST,"empty-check-end-memst", ARG_MEMNUM },\r
+ { OP_EMPTY_CHECK_END_MEMST_PUSH,"empty-check-end-memst-push", ARG_MEMNUM },\r
+ { OP_PREC_READ_START, "push-pos", ARG_NON },\r
+ { OP_PREC_READ_END, "pop-pos", ARG_NON },\r
+ { OP_PREC_READ_NOT_START, "prec-read-not-start", ARG_RELADDR },\r
+ { OP_PREC_READ_NOT_END, "prec-read-not-end", ARG_NON },\r
+ { OP_ATOMIC_START, "atomic-start", ARG_NON },\r
+ { OP_ATOMIC_END, "atomic-end", ARG_NON },\r
+ { OP_LOOK_BEHIND, "look-behind", ARG_SPECIAL },\r
+ { OP_LOOK_BEHIND_NOT_START, "look-behind-not-start", ARG_SPECIAL },\r
+ { OP_LOOK_BEHIND_NOT_END, "look-behind-not-end", ARG_NON },\r
+ { OP_CALL, "call", ARG_ABSADDR },\r
+ { OP_RETURN, "return", ARG_NON },\r
+ { OP_PUSH_SAVE_VAL, "push-save-val", ARG_SPECIAL },\r
+ { OP_UPDATE_VAR, "update-var", ARG_SPECIAL },\r
+#ifdef USE_CALLOUT\r
+ { OP_CALLOUT_CONTENTS, "callout-contents", ARG_SPECIAL },\r
+ { OP_CALLOUT_NAME, "callout-name", ARG_SPECIAL },\r
+#endif\r
+ { -1, "", ARG_NON }\r
+};\r
+\r
+static char*\r
+op2name(int opcode)\r
+{\r
+ int i;\r
+\r
+ for (i = 0; OpInfo[i].opcode >= 0; i++) {\r
+ if (opcode == OpInfo[i].opcode)\r
+ return OpInfo[i].name;\r
+ }\r
+ return "";\r
+}\r
+\r
+static int\r
+op2arg_type(int opcode)\r
+{\r
+ int i;\r
+\r
+ for (i = 0; OpInfo[i].opcode >= 0; i++) {\r
+ if (opcode == OpInfo[i].opcode)\r
+ return OpInfo[i].arg_type;\r
+ }\r
+ return ARG_SPECIAL;\r
+}\r
+\r
+static void\r
+p_string(FILE* f, int len, UChar* s)\r
+{\r
+ fputs(":", f);\r
+ while (len-- > 0) { fputc(*s++, f); }\r
+}\r
+\r
+static void\r
+p_len_string(FILE* f, LengthType len, int mb_len, UChar* s)\r
+{\r
+ int x = len * mb_len;\r
+\r
+ fprintf(f, ":%d:", len);\r
+ while (x-- > 0) { fputc(*s++, f); }\r
+}\r
+\r
+static void\r
+p_rel_addr(FILE* f, RelAddrType rel_addr, UChar* p, UChar* start)\r
+{\r
+ RelAddrType curr = (RelAddrType )(p - start);\r
+\r
+ fprintf(f, "{%d/%d}", rel_addr, curr + rel_addr);\r
+}\r
+\r
+static int\r
+bitset_on_num(BitSetRef bs)\r
+{\r
+ int i, n;\r
+\r
+ n = 0;\r
+ for (i = 0; i < SINGLE_BYTE_SIZE; i++) {\r
+ if (BITSET_AT(bs, i)) n++;\r
+ }\r
+ return n;\r
+}\r
+\r
+extern void\r
+onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp, UChar* start,\r
+ OnigEncoding enc)\r
+{\r
+ int i, n;\r
+ OpArgType arg_type;\r
+ RelAddrType addr;\r
+ LengthType len;\r
+ MemNumType mem;\r
+ OnigCodePoint code;\r
+ OnigOptionType option;\r
+ ModeType mode;\r
+ UChar *q;\r
+\r
+ fprintf(f, "%s", op2name(*bp));\r
+ arg_type = op2arg_type(*bp);\r
+ if (arg_type != ARG_SPECIAL) {\r
+ bp++;\r
+ switch (arg_type) {\r
+ case ARG_NON:\r
+ break;\r
+ case ARG_RELADDR:\r
+ GET_RELADDR_INC(addr, bp);\r
+ fputc(':', f);\r
+ p_rel_addr(f, addr, bp, start);\r
+ break;\r
+ case ARG_ABSADDR:\r
+ GET_ABSADDR_INC(addr, bp);\r
+ fprintf(f, ":{/%d}", addr);\r
+ break;\r
+ case ARG_LENGTH:\r
+ GET_LENGTH_INC(len, bp);\r
+ fprintf(f, ":%d", len);\r
+ break;\r
+ case ARG_MEMNUM:\r
+ mem = *((MemNumType* )bp);\r
+ bp += SIZE_MEMNUM;\r
+ fprintf(f, ":%d", mem);\r
+ break;\r
+ case ARG_OPTION:\r
+ {\r
+ OnigOptionType option = *((OnigOptionType* )bp);\r
+ bp += SIZE_OPTION;\r
+ fprintf(f, ":%d", option);\r
+ }\r
+ break;\r
+ case ARG_MODE:\r
+ mode = *((ModeType* )bp);\r
+ bp += SIZE_MODE;\r
+ fprintf(f, ":%d", mode);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ else {\r
+ switch (*bp++) {\r
+ case OP_EXACT1:\r
+ case OP_ANYCHAR_STAR_PEEK_NEXT:\r
+ case OP_ANYCHAR_ML_STAR_PEEK_NEXT:\r
+ p_string(f, 1, bp++); break;\r
+ case OP_EXACT2:\r
+ p_string(f, 2, bp); bp += 2; break;\r
+ case OP_EXACT3:\r
+ p_string(f, 3, bp); bp += 3; break;\r
+ case OP_EXACT4:\r
+ p_string(f, 4, bp); bp += 4; break;\r
+ case OP_EXACT5:\r
+ p_string(f, 5, bp); bp += 5; break;\r
+ case OP_EXACTN:\r
+ GET_LENGTH_INC(len, bp);\r
+ p_len_string(f, len, 1, bp);\r
+ bp += len;\r
+ break;\r
+\r
+ case OP_EXACTMB2N1:\r
+ p_string(f, 2, bp); bp += 2; break;\r
+ case OP_EXACTMB2N2:\r
+ p_string(f, 4, bp); bp += 4; break;\r
+ case OP_EXACTMB2N3:\r
+ p_string(f, 6, bp); bp += 6; break;\r
+ case OP_EXACTMB2N:\r
+ GET_LENGTH_INC(len, bp);\r
+ p_len_string(f, len, 2, bp);\r
+ bp += len * 2;\r
+ break;\r
+ case OP_EXACTMB3N:\r
+ GET_LENGTH_INC(len, bp);\r
+ p_len_string(f, len, 3, bp);\r
+ bp += len * 3;\r
+ break;\r
+ case OP_EXACTMBN:\r
+ {\r
+ int mb_len;\r
+\r
+ GET_LENGTH_INC(mb_len, bp);\r
+ GET_LENGTH_INC(len, bp);\r
+ fprintf(f, ":%d:%d:", mb_len, len);\r
+ n = len * mb_len;\r
+ while (n-- > 0) { fputc(*bp++, f); }\r
+ }\r
+ break;\r
+\r
+ case OP_EXACT1_IC:\r
+ len = enclen(enc, bp);\r
+ p_string(f, len, bp);\r
+ bp += len;\r
+ break;\r
+ case OP_EXACTN_IC:\r
+ GET_LENGTH_INC(len, bp);\r
+ p_len_string(f, len, 1, bp);\r
+ bp += len;\r
+ break;\r
+\r
+ case OP_CCLASS:\r
+ n = bitset_on_num((BitSetRef )bp);\r
+ bp += SIZE_BITSET;\r
+ fprintf(f, ":%d", n);\r
+ break;\r
+\r
+ case OP_CCLASS_NOT:\r
+ n = bitset_on_num((BitSetRef )bp);\r
+ bp += SIZE_BITSET;\r
+ fprintf(f, ":%d", n);\r
+ break;\r
+\r
+ case OP_CCLASS_MB:\r
+ case OP_CCLASS_MB_NOT:\r
+ GET_LENGTH_INC(len, bp);\r
+ q = bp;\r
+#ifndef PLATFORM_UNALIGNED_WORD_ACCESS\r
+ ALIGNMENT_RIGHT(q);\r
+#endif\r
+ GET_CODE_POINT(code, q);\r
+ bp += len;\r
+ fprintf(f, ":%d:%d", (int )code, len);\r
+ break;\r
+\r
+ case OP_CCLASS_MIX:\r
+ case OP_CCLASS_MIX_NOT:\r
+ n = bitset_on_num((BitSetRef )bp);\r
+ bp += SIZE_BITSET;\r
+ GET_LENGTH_INC(len, bp);\r
+ q = bp;\r
+#ifndef PLATFORM_UNALIGNED_WORD_ACCESS\r
+ ALIGNMENT_RIGHT(q);\r
+#endif\r
+ GET_CODE_POINT(code, q);\r
+ bp += len;\r
+ fprintf(f, ":%d:%d:%d", n, (int )code, len);\r
+ break;\r
+\r
+#ifdef USE_OP_CCLASS_NODE\r
+ case OP_CCLASS_NODE:\r
+ {\r
+ CClassNode *cc;\r
+\r
+ GET_POINTER_INC(cc, bp);\r
+ n = bitset_on_num(cc->bs);\r
+ fprintf(f, ":%p:%d", cc, n);\r
+ }\r
+ break;\r
+#endif\r
+\r
+ case OP_BACKREF_N_IC:\r
+ mem = *((MemNumType* )bp);\r
+ bp += SIZE_MEMNUM;\r
+ fprintf(f, ":%d", mem);\r
+ break;\r
+\r
+ case OP_BACKREF_MULTI_IC:\r
+ case OP_BACKREF_MULTI:\r
+ case OP_BACKREF_CHECK:\r
+ fputs(" ", f);\r
+ GET_LENGTH_INC(len, bp);\r
+ for (i = 0; i < len; i++) {\r
+ GET_MEMNUM_INC(mem, bp);\r
+ if (i > 0) fputs(", ", f);\r
+ fprintf(f, "%d", mem);\r
+ }\r
+ break;\r
+\r
+ case OP_BACKREF_WITH_LEVEL:\r
+ GET_OPTION_INC(option, bp);\r
+ fprintf(f, ":%d", option);\r
+ /* fall */\r
+ case OP_BACKREF_CHECK_WITH_LEVEL:\r
+ {\r
+ LengthType level;\r
+\r
+ GET_LENGTH_INC(level, bp);\r
+ fprintf(f, ":%d", level);\r
+\r
+ fputs(" ", f);\r
+ GET_LENGTH_INC(len, bp);\r
+ for (i = 0; i < len; i++) {\r
+ GET_MEMNUM_INC(mem, bp);\r
+ if (i > 0) fputs(", ", f);\r
+ fprintf(f, "%d", mem);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case OP_REPEAT:\r
+ case OP_REPEAT_NG:\r
+ {\r
+ mem = *((MemNumType* )bp);\r
+ bp += SIZE_MEMNUM;\r
+ addr = *((RelAddrType* )bp);\r
+ bp += SIZE_RELADDR;\r
+ fprintf(f, ":%d:%d", mem, addr);\r
+ }\r
+ break;\r
+\r
+ case OP_PUSH_OR_JUMP_EXACT1:\r
+ case OP_PUSH_IF_PEEK_NEXT:\r
+ addr = *((RelAddrType* )bp);\r
+ bp += SIZE_RELADDR;\r
+ fputc(':', f);\r
+ p_rel_addr(f, addr, bp, start);\r
+ p_string(f, 1, bp);\r
+ bp += 1;\r
+ break;\r
+\r
+ case OP_LOOK_BEHIND:\r
+ GET_LENGTH_INC(len, bp);\r
+ fprintf(f, ":%d", len);\r
+ break;\r
+\r
+ case OP_LOOK_BEHIND_NOT_START:\r
+ GET_RELADDR_INC(addr, bp);\r
+ GET_LENGTH_INC(len, bp);\r
+ fprintf(f, ":%d:", len);\r
+ p_rel_addr(f, addr, bp, start);\r
+ break;\r
+\r
+ case OP_PUSH_SAVE_VAL:\r
+ {\r
+ SaveType type;\r
+ GET_SAVE_TYPE_INC(type, bp);\r
+ GET_MEMNUM_INC(mem, bp);\r
+ fprintf(f, ":%d:%d", type, mem);\r
+ }\r
+ break;\r
+\r
+ case OP_UPDATE_VAR:\r
+ {\r
+ UpdateVarType type;\r
+ GET_UPDATE_VAR_TYPE_INC(type, bp);\r
+ GET_MEMNUM_INC(mem, bp);\r
+ fprintf(f, ":%d:%d", type, mem);\r
+ }\r
+ break;\r
+\r
+#ifdef USE_CALLOUT\r
+ case OP_CALLOUT_CONTENTS:\r
+ {\r
+ GET_MEMNUM_INC(mem, bp); /* number */\r
+ fprintf(f, ":%d", mem);\r
+ }\r
+ break;\r
+\r
+ case OP_CALLOUT_NAME:\r
+ {\r
+ int id;\r
+\r
+ GET_MEMNUM_INC(id, bp); /* id */\r
+ GET_MEMNUM_INC(mem, bp); /* number */\r
+\r
+ fprintf(f, ":%d:%d", id, mem);\r
+ }\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n", *--bp);\r
+ }\r
+ }\r
+ if (nextp) *nextp = bp;\r
+}\r
+#endif /* ONIG_DEBUG */\r
+\r
+#ifdef ONIG_DEBUG_COMPILE\r
+extern void\r
+onig_print_compiled_byte_code_list(FILE* f, regex_t* reg)\r
+{\r
+ UChar* bp;\r
+ UChar* start = reg->p;\r
+ UChar* end = reg->p + reg->used;\r
+\r
+ fprintf(f, "bt_mem_start: 0x%x, bt_mem_end: 0x%x\n",\r
+ reg->bt_mem_start, reg->bt_mem_end);\r
+ fprintf(f, "code-length: %d\n", reg->used);\r
+\r
+ bp = start;\r
+ while (bp < end) {\r
+ int pos = bp - start;\r
+\r
+ fprintf(f, "%4d: ", pos);\r
+ onig_print_compiled_byte_code(f, bp, &bp, start, reg->enc);\r
+ fprintf(f, "\n");\r
+ }\r
+ fprintf(f, "\n");\r
+}\r
+#endif\r
+\r
+\r
#ifdef USE_CAPTURE_HISTORY\r
static void history_tree_free(OnigCaptureTreeNode* node);\r
\r
OnigRegion* r;\r
\r
r = (OnigRegion* )xmalloc(sizeof(OnigRegion));\r
+ CHECK_NULL_RETURN(r);\r
onig_region_init(r);\r
return r;\r
}\r
extern void\r
onig_region_free(OnigRegion* r, int free_self)\r
{\r
- if (r) {\r
+ if (r != 0) {\r
if (r->allocated > 0) {\r
if (r->beg) xfree(r->beg);\r
if (r->end) xfree(r->end);\r
if (to->allocated == 0) {\r
if (from->num_regs > 0) {\r
to->beg = (int* )xmalloc(RREGC_SIZE);\r
+ if (IS_NULL(to->beg)) return;\r
to->end = (int* )xmalloc(RREGC_SIZE);\r
+ if (IS_NULL(to->end)) return;\r
to->allocated = from->num_regs;\r
}\r
}\r
else if (to->allocated < from->num_regs) {\r
to->beg = (int* )xrealloc(to->beg, RREGC_SIZE, sizeof(int) * to->allocated);\r
+ if (IS_NULL(to->beg)) return;\r
to->end = (int* )xrealloc(to->end, RREGC_SIZE, sizeof(int) * to->allocated);\r
+ if (IS_NULL(to->end)) return;\r
to->allocated = from->num_regs;\r
}\r
\r
#endif\r
}\r
\r
+#ifdef USE_CALLOUT\r
+#define CALLOUT_BODY(func, ain, aname_id, anum, user, args, result) do { \\r
+ args.in = (ain);\\r
+ args.name_id = (aname_id);\\r
+ args.num = anum;\\r
+ args.regex = reg;\\r
+ args.string = str;\\r
+ args.string_end = end;\\r
+ args.start = sstart;\\r
+ args.right_range = right_range;\\r
+ args.current = s;\\r
+ args.retry_in_match_counter = retry_in_match_counter;\\r
+ args.msa = msa;\\r
+ args.stk_base = stk_base;\\r
+ args.stk = stk;\\r
+ args.mem_start_stk = mem_start_stk;\\r
+ args.mem_end_stk = mem_end_stk;\\r
+ result = (func)(&args, user);\\r
+} while (0)\r
+\r
+#define RETRACTION_CALLOUT(func, aname_id, anum, user) do {\\r
+ int result;\\r
+ OnigCalloutArgs args;\\r
+ CALLOUT_BODY(func, ONIG_CALLOUT_IN_RETRACTION, aname_id, anum, user, args, result);\\r
+ switch (result) {\\r
+ case ONIG_CALLOUT_FAIL:\\r
+ case ONIG_CALLOUT_SUCCESS:\\r
+ break;\\r
+ default:\\r
+ if (result > 0) {\\r
+ result = ONIGERR_INVALID_ARGUMENT;\\r
+ }\\r
+ best_len = result;\\r
+ goto finish;\\r
+ break;\\r
+ }\\r
+} while(0)\r
+#endif\r
+\r
\r
/** stack **/\r
#define INVALID_STACK_INDEX -1\r
\r
+#define STK_ALT_FLAG 0x0001\r
+\r
/* stack type */\r
/* used by normal-POP */\r
-#define STK_ALT 0x0001\r
-#define STK_LOOK_BEHIND_NOT 0x0002\r
-#define STK_POS_NOT 0x0003\r
+#define STK_SUPER_ALT STK_ALT_FLAG\r
+#define STK_ALT (0x0002 | STK_ALT_FLAG)\r
+#define STK_ALT_PREC_READ_NOT (0x0004 | STK_ALT_FLAG)\r
+#define STK_ALT_LOOK_BEHIND_NOT (0x0006 | STK_ALT_FLAG)\r
+\r
/* handled by normal-POP */\r
-#define STK_MEM_START 0x0100\r
-#define STK_MEM_END 0x8200\r
-#define STK_REPEAT_INC 0x0300\r
-#define STK_STATE_CHECK_MARK 0x1000\r
+#define STK_MEM_START 0x0010\r
+#define STK_MEM_END 0x8030\r
+#define STK_REPEAT_INC 0x0050\r
+#ifdef USE_CALLOUT\r
+#define STK_CALLOUT 0x0070\r
+#endif\r
+\r
/* avoided by normal-POP */\r
-#define STK_NULL_CHECK_START 0x3000\r
-#define STK_NULL_CHECK_END 0x5000 /* for recursive call */\r
-#define STK_MEM_END_MARK 0x8400\r
-#define STK_POS 0x0500 /* used when POP-POS */\r
-#define STK_STOP_BT 0x0600 /* mark for "(?>...)" */\r
-#define STK_REPEAT 0x0700\r
-#define STK_CALL_FRAME 0x0800\r
-#define STK_RETURN 0x0900\r
-#define STK_VOID 0x0a00 /* for fill a blank */\r
+#define STK_VOID 0x0000 /* for fill a blank */\r
+#define STK_EMPTY_CHECK_START 0x3000\r
+#define STK_EMPTY_CHECK_END 0x5000 /* for recursive call */\r
+#define STK_MEM_END_MARK 0x8100\r
+#define STK_TO_VOID_START 0x1200 /* mark for "(?>...)" */\r
+#define STK_REPEAT 0x0300\r
+#define STK_CALL_FRAME 0x0400\r
+#define STK_RETURN 0x0500\r
+#define STK_SAVE_VAL 0x0600\r
\r
/* stack type check mask */\r
-#define STK_MASK_POP_USED 0x00ff\r
-#define STK_MASK_TO_VOID_TARGET 0x10ff\r
+#define STK_MASK_POP_USED STK_ALT_FLAG\r
+#define STK_MASK_POP_HANDLED 0x0010\r
+#define STK_MASK_POP_HANDLED_TIL (STK_MASK_POP_HANDLED | 0x0004)\r
+#define STK_MASK_TO_VOID_TARGET 0x100e\r
#define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */\r
\r
+typedef intptr_t StackIndex;\r
+\r
+typedef struct _StackType {\r
+ unsigned int type;\r
+ int zid;\r
+ union {\r
+ struct {\r
+ UChar *pcode; /* byte code position */\r
+ UChar *pstr; /* string position */\r
+ UChar *pstr_prev; /* previous char position of pstr */\r
+ } state;\r
+ struct {\r
+ int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */\r
+ UChar *pcode; /* byte code position (head of repeated target) */\r
+ } repeat;\r
+ struct {\r
+ StackIndex si; /* index of stack */\r
+ } repeat_inc;\r
+ struct {\r
+ UChar *pstr; /* start/end position */\r
+ /* Following information is set, if this stack type is MEM-START */\r
+ StackIndex prev_start; /* prev. info (for backtrack "(...)*" ) */\r
+ StackIndex prev_end; /* prev. info (for backtrack "(...)*" ) */\r
+ } mem;\r
+ struct {\r
+ UChar *pstr; /* start position */\r
+ } empty_check;\r
+#ifdef USE_CALL\r
+ struct {\r
+ UChar *ret_addr; /* byte code position */\r
+ UChar *pstr; /* string position */\r
+ } call_frame;\r
+#endif\r
+ struct {\r
+ enum SaveType type;\r
+ UChar* v;\r
+ UChar* v2;\r
+ } val;\r
+#ifdef USE_CALLOUT\r
+ struct {\r
+ int num;\r
+ OnigCalloutFunc func;\r
+ } callout;\r
+#endif\r
+ } u;\r
+} StackType;\r
+\r
+#ifdef USE_CALLOUT\r
+\r
+struct OnigCalloutArgsStruct {\r
+ OnigCalloutIn in;\r
+ int name_id; /* name id or ONIG_NON_NAME_ID */\r
+ int num;\r
+ OnigRegex regex;\r
+ const OnigUChar* string;\r
+ const OnigUChar* string_end;\r
+ const OnigUChar* start;\r
+ const OnigUChar* right_range;\r
+ const OnigUChar* current; /* current matching position */\r
+ unsigned long retry_in_match_counter;\r
+\r
+ /* invisible to users */\r
+ MatchArg* msa;\r
+ StackType* stk_base;\r
+ StackType* stk;\r
+ StackIndex* mem_start_stk;\r
+ StackIndex* mem_end_stk;\r
+};\r
+\r
+#endif\r
+\r
+\r
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
-#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\\r
+#define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mp) do { \\r
(msa).stack_p = (void* )0;\\r
(msa).options = (arg_option);\\r
(msa).region = (arg_region);\\r
(msa).start = (arg_start);\\r
+ (msa).match_stack_limit = (mp)->match_stack_limit;\\r
+ (msa).retry_limit_in_match = (mp)->retry_limit_in_match;\\r
+ (msa).mp = mp;\\r
(msa).best_len = ONIG_MISMATCH;\\r
+ (msa).ptr_num = (reg)->num_repeat + ((reg)->num_mem + 1) * 2; \\r
} while(0)\r
#else\r
-#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\\r
+#define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mp) do { \\r
(msa).stack_p = (void* )0;\\r
(msa).options = (arg_option);\\r
(msa).region = (arg_region);\\r
(msa).start = (arg_start);\\r
+ (msa).match_stack_limit = (mp)->match_stack_limit;\\r
+ (msa).retry_limit_in_match = (mp)->retry_limit_in_match;\\r
+ (msa).mp = mp;\\r
+ (msa).ptr_num = (reg)->num_repeat + ((reg)->num_mem + 1) * 2; \\r
} while(0)\r
#endif\r
\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
-\r
-#define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE 16\r
-\r
-#define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do { \\r
- if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\\r
- unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\\r
- offset = ((offset) * (state_num)) >> 3;\\r
- if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\\r
- if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) \\r
- (msa).state_check_buff = (void* )xmalloc(size);\\r
- else \\r
- (msa).state_check_buff = (void* )xalloca(size);\\r
- xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \\r
- (size_t )(size - (offset))); \\r
- (msa).state_check_buff_size = size;\\r
- }\\r
- else {\\r
- (msa).state_check_buff = (void* )0;\\r
- (msa).state_check_buff_size = 0;\\r
- }\\r
- }\\r
- else {\\r
- (msa).state_check_buff = (void* )0;\\r
- (msa).state_check_buff_size = 0;\\r
- }\\r
- } while(0)\r
-\r
-#define MATCH_ARG_FREE(msa) do {\\r
- if ((msa).stack_p) xfree((msa).stack_p);\\r
- if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \\r
- if ((msa).state_check_buff) xfree((msa).state_check_buff);\\r
- }\\r
-} while(0)\r
-#else\r
-#define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num)\r
#define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)\r
-#endif\r
\r
\r
+#define ALLOCA_PTR_NUM_LIMIT 50\r
\r
-#define STACK_INIT(alloc_addr, ptr_num, stack_num) do {\\r
+#define STACK_INIT(stack_num) do {\\r
if (msa->stack_p) {\\r
- alloc_addr = (char* )xmalloc(sizeof(char*) * (ptr_num));\\r
- stk_alloc = (OnigStackType* )(msa->stack_p);\\r
- stk_base = stk_alloc;\\r
+ is_alloca = 0;\\r
+ alloc_base = msa->stack_p;\\r
+ stk_base = (StackType* )(alloc_base\\r
+ + (sizeof(StackIndex) * msa->ptr_num));\\r
stk = stk_base;\\r
stk_end = stk_base + msa->stack_n;\\r
}\\r
+ else if (msa->ptr_num > ALLOCA_PTR_NUM_LIMIT) {\\r
+ is_alloca = 0;\\r
+ alloc_base = (char* )xmalloc(sizeof(StackIndex) * msa->ptr_num\\r
+ + sizeof(StackType) * (stack_num));\\r
+ CHECK_NULL_RETURN_MEMERR(alloc_base);\\r
+ stk_base = (StackType* )(alloc_base\\r
+ + (sizeof(StackIndex) * msa->ptr_num));\\r
+ stk = stk_base;\\r
+ stk_end = stk_base + (stack_num);\\r
+ }\\r
else {\\r
- alloc_addr = (char* )xmalloc(sizeof(char*) * (ptr_num)\\r
- + sizeof(OnigStackType) * (stack_num));\\r
- stk_alloc = (OnigStackType* )(alloc_addr + sizeof(char*) * (ptr_num));\\r
- stk_base = stk_alloc;\\r
+ is_alloca = 1;\\r
+ alloc_base = (char* )xmalloc(sizeof(StackIndex) * msa->ptr_num\\r
+ + sizeof(StackType) * (stack_num));\\r
+ CHECK_NULL_RETURN_MEMERR(alloc_base);\\r
+ stk_base = (StackType* )(alloc_base\\r
+ + (sizeof(StackIndex) * msa->ptr_num));\\r
stk = stk_base;\\r
stk_end = stk_base + (stack_num);\\r
}\\r
-} while(0)\r
+} while(0);\r
+\r
\r
#define STACK_SAVE do{\\r
- if (stk_base != stk_alloc) {\\r
- msa->stack_p = stk_base;\\r
- msa->stack_n = (int)(stk_end - stk_base);\\r
+ msa->stack_n = (int )(stk_end - stk_base);\\r
+ if (is_alloca != 0) {\\r
+ size_t size = sizeof(StackIndex) * msa->ptr_num \\r
+ + sizeof(StackType) * msa->stack_n;\\r
+ msa->stack_p = xmalloc(size);\\r
+ CHECK_NULL_RETURN_MEMERR(msa->stack_p);\\r
+ xmemcpy(msa->stack_p, alloc_base, size);\\r
+ }\\r
+ else {\\r
+ msa->stack_p = alloc_base;\\r
};\\r
} while(0)\r
\r
-static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;\r
+#define UPDATE_FOR_STACK_REALLOC do{\\r
+ repeat_stk = (StackIndex* )alloc_base;\\r
+ mem_start_stk = (StackIndex* )(repeat_stk + reg->num_repeat);\\r
+ mem_end_stk = mem_start_stk + num_mem + 1;\\r
+} while(0)\r
+\r
+static unsigned int MatchStackLimit = DEFAULT_MATCH_STACK_LIMIT_SIZE;\r
\r
extern unsigned int\r
onig_get_match_stack_limit_size(void)\r
{\r
- return MatchStackLimitSize;\r
+ return MatchStackLimit;\r
}\r
\r
extern int\r
onig_set_match_stack_limit_size(unsigned int size)\r
{\r
- MatchStackLimitSize = size;\r
+ MatchStackLimit = size;\r
return 0;\r
}\r
\r
-static int\r
-stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,\r
- OnigStackType** arg_stk, OnigStackType* stk_alloc, OnigMatchArg* msa)\r
-{\r
- unsigned int n;\r
- OnigStackType *x, *stk_base, *stk_end, *stk;\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
\r
- stk_base = *arg_stk_base;\r
- stk_end = *arg_stk_end;\r
- stk = *arg_stk;\r
+static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH;\r
\r
- n = (unsigned int)(stk_end - stk_base);\r
- if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {\r
- x = (OnigStackType* )xmalloc(sizeof(OnigStackType) * n * 2);\r
- if (IS_NULL(x)) {\r
- STACK_SAVE;\r
- return ONIGERR_MEMORY;\r
- }\r
- xmemcpy(x, stk_base, n * sizeof(OnigStackType));\r
- n *= 2;\r
- }\r
- else {\r
- n *= 2;\r
- if (MatchStackLimitSize != 0 && n > MatchStackLimitSize) {\r
- if ((unsigned int )(stk_end - stk_base) == MatchStackLimitSize)\r
- return ONIGERR_MATCH_STACK_LIMIT_OVER;\r
- else\r
- n = MatchStackLimitSize;\r
- }\r
- x = (OnigStackType* )xrealloc(stk_base, sizeof(OnigStackType) * n, sizeof(OnigStackType) * (stk_end - stk_base));\r
- if (IS_NULL(x)) {\r
- STACK_SAVE;\r
- return ONIGERR_MEMORY;\r
- }\r
- }\r
- *arg_stk = x + (stk - stk_base);\r
- *arg_stk_base = x;\r
- *arg_stk_end = x + n;\r
- return 0;\r
-}\r
+#define CHECK_RETRY_LIMIT_IN_MATCH do {\\r
+ if (retry_in_match_counter++ > retry_limit_in_match) goto retry_limit_in_match_over;\\r
+} while (0)\r
\r
-#define STACK_ENSURE(n) do {\\r
- if (stk_end - stk < (n)) {\\r
- int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\\r
- if (r != 0) { STACK_SAVE; return r; } \\r
- }\\r
-} while(0)\r
+#else\r
\r
-#define STACK_AT(index) (stk_base + (index))\r
-#define GET_STACK_INDEX(stk) ((OnigStackIndex)((stk) - stk_base))\r
+#define CHECK_RETRY_LIMIT_IN_MATCH\r
\r
-#define STACK_PUSH_TYPE(stack_type) do {\\r
- STACK_ENSURE(1);\\r
- stk->type = (stack_type);\\r
- STACK_INC;\\r
-} while(0)\r
+#endif /* USE_RETRY_LIMIT_IN_MATCH */\r
\r
-#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)\r
+extern unsigned long\r
+onig_get_retry_limit_in_match(void)\r
+{\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ return RetryLimitInMatch;\r
+#else\r
+ /* return ONIG_NO_SUPPORT_CONFIG; */\r
+ return 0;\r
+#endif\r
+}\r
\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
-#define STATE_CHECK_POS(s,snum) \\r
- (((s) - str) * num_comb_exp_check + ((snum) - 1))\r
-#define STATE_CHECK_VAL(v,snum) do {\\r
- if (state_check_buff != NULL) {\\r
- int x = STATE_CHECK_POS(s,snum);\\r
- (v) = state_check_buff[x/8] & (1<<(x%8));\\r
- }\\r
- else (v) = 0;\\r
-} while(0)\r
+extern int\r
+onig_set_retry_limit_in_match(unsigned long size)\r
+{\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ RetryLimitInMatch = size;\r
+ return 0;\r
+#else\r
+ return ONIG_NO_SUPPORT_CONFIG;\r
+#endif\r
+}\r
\r
+static OnigCalloutFunc DefaultProgressCallout;\r
+static OnigCalloutFunc DefaultRetractionCallout;\r
\r
-#define ELSE_IF_STATE_CHECK_MARK(stk) \\r
- else if ((stk)->type == STK_STATE_CHECK_MARK) { \\r
- int x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\\r
- state_check_buff[x/8] |= (1<<(x%8)); \\r
+extern OnigMatchParam*\r
+onig_new_match_param(void)\r
+{\r
+ OnigMatchParam* p;\r
+\r
+ p = (OnigMatchParam* )xmalloc(sizeof(*p));\r
+ if (IS_NOT_NULL(p)) {\r
+ onig_initialize_match_param(p);\r
}\r
\r
-#define STACK_PUSH(stack_type,pat,s,sprev) do {\\r
- STACK_ENSURE(1);\\r
- stk->type = (stack_type);\\r
- stk->u.state.pcode = (pat);\\r
- stk->u.state.pstr = (s);\\r
- stk->u.state.pstr_prev = (sprev);\\r
- stk->u.state.state_check = 0;\\r
- STACK_INC;\\r
-} while(0)\r
+ return p;\r
+}\r
\r
-#define STACK_PUSH_ENSURED(stack_type,pat) do {\\r
- stk->type = (stack_type);\\r
- stk->u.state.pcode = (pat);\\r
- stk->u.state.state_check = 0;\\r
- STACK_INC;\\r
-} while(0)\r
+extern void\r
+onig_free_match_param_content(OnigMatchParam* p)\r
+{\r
+#ifdef USE_CALLOUT\r
+ if (IS_NOT_NULL(p->callout_data)) {\r
+ xfree(p->callout_data);\r
+ p->callout_data = 0;\r
+ }\r
+#endif\r
+}\r
\r
-#define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum) do {\\r
- STACK_ENSURE(1);\\r
- stk->type = STK_ALT;\\r
- stk->u.state.pcode = (pat);\\r
- stk->u.state.pstr = (s);\\r
- stk->u.state.pstr_prev = (sprev);\\r
- stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\\r
- STACK_INC;\\r
-} while(0)\r
+extern void\r
+onig_free_match_param(OnigMatchParam* p)\r
+{\r
+ if (IS_NOT_NULL(p)) {\r
+ onig_free_match_param_content(p);\r
+ xfree(p);\r
+ }\r
+}\r
+\r
+extern int\r
+onig_initialize_match_param(OnigMatchParam* mp)\r
+{\r
+ mp->match_stack_limit = MatchStackLimit;\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ mp->retry_limit_in_match = RetryLimitInMatch;\r
+#endif\r
+ mp->progress_callout_of_contents = DefaultProgressCallout;\r
+ mp->retraction_callout_of_contents = DefaultRetractionCallout;\r
+\r
+#ifdef USE_CALLOUT\r
+ mp->match_at_call_counter = 0;\r
+ mp->callout_user_data = 0;\r
+ mp->callout_data = 0;\r
+ mp->callout_data_alloc_num = 0;\r
+#endif\r
+\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+#ifdef USE_CALLOUT\r
+\r
+static int\r
+adjust_match_param(regex_t* reg, OnigMatchParam* mp)\r
+{\r
+ RegexExt* ext = REG_EXTP(reg);\r
+\r
+ mp->match_at_call_counter = 0;\r
+\r
+ if (IS_NULL(ext) || ext->callout_num == 0) return ONIG_NORMAL;\r
+\r
+ if (ext->callout_num > mp->callout_data_alloc_num) {\r
+ CalloutData* d;\r
+ size_t n = ext->callout_num * sizeof(*d);\r
+ if (IS_NOT_NULL(mp->callout_data))\r
+ d = (CalloutData* )xrealloc(mp->callout_data, n, mp->callout_data_alloc_num * sizeof(*d));\r
+ else\r
+ d = (CalloutData* )xmalloc(n);\r
+ CHECK_NULL_RETURN_MEMERR(d);\r
+\r
+ mp->callout_data = d;\r
+ mp->callout_data_alloc_num = ext->callout_num;\r
+ }\r
+\r
+ xmemset(mp->callout_data, 0, mp->callout_data_alloc_num * sizeof(CalloutData));\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+#define ADJUST_MATCH_PARAM(reg, mp) \\r
+ r = adjust_match_param(reg, mp);\\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+#define CALLOUT_DATA_AT_NUM(mp, num) ((mp)->callout_data + ((num) - 1))\r
+\r
+extern int\r
+onig_check_callout_data_and_clear_old_values(OnigCalloutArgs* args)\r
+{\r
+ OnigMatchParam* mp;\r
+ int num;\r
+ CalloutData* d;\r
+\r
+ mp = args->msa->mp;\r
+ num = args->num;\r
+\r
+ d = CALLOUT_DATA_AT_NUM(mp, num);\r
+ if (d->last_match_at_call_counter != mp->match_at_call_counter) {\r
+ xmemset(d, 0, sizeof(*d));\r
+ d->last_match_at_call_counter = mp->match_at_call_counter;\r
+ return d->last_match_at_call_counter;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+extern int\r
+onig_get_callout_data_dont_clear_old(regex_t* reg, OnigMatchParam* mp,\r
+ int callout_num, int slot,\r
+ OnigType* type, OnigValue* val)\r
+{\r
+ OnigType t;\r
+ CalloutData* d;\r
+\r
+ if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
+\r
+ d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
+ t = d->slot[slot].type;\r
+ if (IS_NOT_NULL(type)) *type = t;\r
+ if (IS_NOT_NULL(val)) *val = d->slot[slot].val;\r
+ return (t == ONIG_TYPE_VOID ? 1 : ONIG_NORMAL);\r
+}\r
+\r
+extern int\r
+onig_get_callout_data_by_callout_args_self_dont_clear_old(OnigCalloutArgs* args,\r
+ int slot, OnigType* type,\r
+ OnigValue* val)\r
+{\r
+ return onig_get_callout_data_dont_clear_old(args->regex, args->msa->mp,\r
+ args->num, slot, type, val);\r
+}\r
+\r
+extern int\r
+onig_get_callout_data(regex_t* reg, OnigMatchParam* mp,\r
+ int callout_num, int slot,\r
+ OnigType* type, OnigValue* val)\r
+{\r
+ OnigType t;\r
+ CalloutData* d;\r
+\r
+ if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
+\r
+ d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
+ if (d->last_match_at_call_counter != mp->match_at_call_counter) {\r
+ xmemset(d, 0, sizeof(*d));\r
+ d->last_match_at_call_counter = mp->match_at_call_counter;\r
+ }\r
+\r
+ t = d->slot[slot].type;\r
+ if (IS_NOT_NULL(type)) *type = t;\r
+ if (IS_NOT_NULL(val)) *val = d->slot[slot].val;\r
+ return (t == ONIG_TYPE_VOID ? 1 : ONIG_NORMAL);\r
+}\r
+\r
+extern int\r
+onig_get_callout_data_by_tag(regex_t* reg, OnigMatchParam* mp,\r
+ const UChar* tag, const UChar* tag_end, int slot,\r
+ OnigType* type, OnigValue* val)\r
+{\r
+ int num;\r
+\r
+ num = onig_get_callout_num_by_tag(reg, tag, tag_end);\r
+ if (num < 0) return num;\r
+ if (num == 0) return ONIGERR_INVALID_CALLOUT_TAG_NAME;\r
+\r
+ return onig_get_callout_data(reg, mp, num, slot, type, val);\r
+}\r
+\r
+extern int\r
+onig_get_callout_data_by_callout_args(OnigCalloutArgs* args,\r
+ int callout_num, int slot,\r
+ OnigType* type, OnigValue* val)\r
+{\r
+ return onig_get_callout_data(args->regex, args->msa->mp, callout_num, slot,\r
+ type, val);\r
+}\r
+\r
+extern int\r
+onig_get_callout_data_by_callout_args_self(OnigCalloutArgs* args,\r
+ int slot, OnigType* type, OnigValue* val)\r
+{\r
+ return onig_get_callout_data(args->regex, args->msa->mp, args->num, slot,\r
+ type, val);\r
+}\r
+\r
+extern int\r
+onig_set_callout_data(regex_t* reg, OnigMatchParam* mp,\r
+ int callout_num, int slot,\r
+ OnigType type, OnigValue* val)\r
+{\r
+ CalloutData* d;\r
+\r
+ if (callout_num <= 0) return ONIGERR_INVALID_ARGUMENT;\r
+\r
+ d = CALLOUT_DATA_AT_NUM(mp, callout_num);\r
+ d->slot[slot].type = type;\r
+ d->slot[slot].val = *val;\r
+ d->last_match_at_call_counter = mp->match_at_call_counter;\r
+\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern int\r
+onig_set_callout_data_by_tag(regex_t* reg, OnigMatchParam* mp,\r
+ const UChar* tag, const UChar* tag_end, int slot,\r
+ OnigType type, OnigValue* val)\r
+{\r
+ int num;\r
+\r
+ num = onig_get_callout_num_by_tag(reg, tag, tag_end);\r
+ if (num < 0) return num;\r
+ if (num == 0) return ONIGERR_INVALID_CALLOUT_TAG_NAME;\r
+\r
+ return onig_set_callout_data(reg, mp, num, slot, type, val);\r
+}\r
+\r
+extern int\r
+onig_set_callout_data_by_callout_args(OnigCalloutArgs* args,\r
+ int callout_num, int slot,\r
+ OnigType type, OnigValue* val)\r
+{\r
+ return onig_set_callout_data(args->regex, args->msa->mp, callout_num, slot,\r
+ type, val);\r
+}\r
+\r
+extern int\r
+onig_set_callout_data_by_callout_args_self(OnigCalloutArgs* args,\r
+ int slot, OnigType type, OnigValue* val)\r
+{\r
+ return onig_set_callout_data(args->regex, args->msa->mp, args->num, slot,\r
+ type, val);\r
+}\r
\r
-#define STACK_PUSH_STATE_CHECK(s,snum) do {\\r
- if (state_check_buff != NULL) {\\r
- STACK_ENSURE(1);\\r
- stk->type = STK_STATE_CHECK_MARK;\\r
- stk->u.state.pstr = (s);\\r
- stk->u.state.state_check = (snum);\\r
- STACK_INC;\\r
+#else\r
+#define ADJUST_MATCH_PARAM(reg, mp)\r
+#endif /* USE_CALLOUT */\r
+\r
+\r
+static int\r
+stack_double(int is_alloca, char** arg_alloc_base,\r
+ StackType** arg_stk_base, StackType** arg_stk_end, StackType** arg_stk,\r
+ MatchArg* msa)\r
+{\r
+ unsigned int n;\r
+ int used;\r
+ size_t size;\r
+ size_t new_size;\r
+ char* alloc_base;\r
+ char* new_alloc_base;\r
+ StackType *stk_base, *stk_end, *stk;\r
+\r
+ alloc_base = *arg_alloc_base;\r
+ stk_base = *arg_stk_base;\r
+ stk_end = *arg_stk_end;\r
+ stk = *arg_stk;\r
+\r
+ n = (unsigned int )(stk_end - stk_base);\r
+ size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n;\r
+ n *= 2;\r
+ new_size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n;\r
+ if (is_alloca != 0) {\r
+ new_alloc_base = (char* )xmalloc(new_size);\r
+ if (IS_NULL(new_alloc_base)) {\r
+ STACK_SAVE;\r
+ return ONIGERR_MEMORY;\r
+ }\r
+ xmemcpy(new_alloc_base, alloc_base, size);\r
+ }\r
+ else {\r
+ if (msa->match_stack_limit != 0 && n > msa->match_stack_limit) {\r
+ if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit)\r
+ return ONIGERR_MATCH_STACK_LIMIT_OVER;\r
+ else\r
+ n = msa->match_stack_limit;\r
+ }\r
+ new_alloc_base = (char* )xrealloc(alloc_base, new_size, size);\r
+ if (IS_NULL(new_alloc_base)) {\r
+ STACK_SAVE;\r
+ return ONIGERR_MEMORY;\r
+ }\r
+ }\r
+\r
+ alloc_base = new_alloc_base;\r
+ used = (int )(stk - stk_base);\r
+ *arg_alloc_base = alloc_base;\r
+ *arg_stk_base = (StackType* )(alloc_base\r
+ + (sizeof(StackIndex) * msa->ptr_num));\r
+ *arg_stk = *arg_stk_base + used;\r
+ *arg_stk_end = *arg_stk_base + n;\r
+ return 0;\r
+}\r
+\r
+#define STACK_ENSURE(n) do {\\r
+ if ((int )(stk_end - stk) < (n)) {\\r
+ int r = stack_double(is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\\r
+ if (r != 0) { STACK_SAVE; return r; } \\r
+ is_alloca = 0;\\r
+ UPDATE_FOR_STACK_REALLOC;\\r
}\\r
} while(0)\r
\r
-#else /* USE_COMBINATION_EXPLOSION_CHECK */\r
+#define STACK_AT(index) (stk_base + (index))\r
+#define GET_STACK_INDEX(stk) ((stk) - stk_base)\r
+\r
+#define STACK_PUSH_TYPE(stack_type) do {\\r
+ STACK_ENSURE(1);\\r
+ stk->type = (stack_type);\\r
+ STACK_INC;\\r
+} while(0)\r
\r
-#define ELSE_IF_STATE_CHECK_MARK(stk)\r
+#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)\r
\r
#define STACK_PUSH(stack_type,pat,s,sprev) do {\\r
STACK_ENSURE(1);\\r
stk->u.state.pcode = (pat);\\r
STACK_INC;\\r
} while(0)\r
-#endif /* USE_COMBINATION_EXPLOSION_CHECK */\r
\r
-#define STACK_PUSH_ALT(pat,s,sprev) STACK_PUSH(STK_ALT,pat,s,sprev)\r
-#define STACK_PUSH_POS(s,sprev) STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev)\r
-#define STACK_PUSH_POS_NOT(pat,s,sprev) STACK_PUSH(STK_POS_NOT,pat,s,sprev)\r
-#define STACK_PUSH_STOP_BT STACK_PUSH_TYPE(STK_STOP_BT)\r
-#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev) \\r
- STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev)\r
+#ifdef ONIG_DEBUG_MATCH\r
+#define STACK_PUSH_BOTTOM(stack_type,pat) do {\\r
+ stk->type = (stack_type);\\r
+ stk->u.state.pcode = (pat);\\r
+ stk->u.state.pstr = s;\\r
+ stk->u.state.pstr_prev = sprev;\\r
+ STACK_INC;\\r
+} while (0)\r
+#else\r
+#define STACK_PUSH_BOTTOM(stack_type,pat) do {\\r
+ stk->type = (stack_type);\\r
+ stk->u.state.pcode = (pat);\\r
+ STACK_INC;\\r
+} while (0)\r
+#endif\r
\r
-#define STACK_PUSH_REPEAT(id, pat) do {\\r
+#define STACK_PUSH_ALT(pat,s,sprev) STACK_PUSH(STK_ALT,pat,s,sprev)\r
+#define STACK_PUSH_SUPER_ALT(pat,s,sprev) STACK_PUSH(STK_SUPER_ALT,pat,s,sprev)\r
+#define STACK_PUSH_POS(s,sprev) \\r
+ STACK_PUSH(STK_TO_VOID_START,NULL_UCHARP,s,sprev)\r
+#define STACK_PUSH_ALT_PREC_READ_NOT(pat,s,sprev) \\r
+ STACK_PUSH(STK_ALT_PREC_READ_NOT,pat,s,sprev)\r
+#define STACK_PUSH_TO_VOID_START STACK_PUSH_TYPE(STK_TO_VOID_START)\r
+#define STACK_PUSH_ALT_LOOK_BEHIND_NOT(pat,s,sprev) \\r
+ STACK_PUSH(STK_ALT_LOOK_BEHIND_NOT,pat,s,sprev)\r
+\r
+#define STACK_PUSH_REPEAT(sid, pat) do {\\r
STACK_ENSURE(1);\\r
stk->type = STK_REPEAT;\\r
- stk->u.repeat.num = (id);\\r
+ stk->zid = (sid);\\r
stk->u.repeat.pcode = (pat);\\r
stk->u.repeat.count = 0;\\r
STACK_INC;\\r
#define STACK_PUSH_MEM_START(mnum, s) do {\\r
STACK_ENSURE(1);\\r
stk->type = STK_MEM_START;\\r
- stk->u.mem.num = (int)(mnum);\\r
- stk->u.mem.pstr = (s);\\r
- stk->u.mem.start = mem_start_stk[mnum];\\r
- stk->u.mem.end = mem_end_stk[mnum];\\r
- mem_start_stk[mnum] = GET_STACK_INDEX(stk);\\r
- mem_end_stk[mnum] = INVALID_STACK_INDEX;\\r
+ stk->zid = (mnum);\\r
+ stk->u.mem.pstr = (s);\\r
+ stk->u.mem.prev_start = mem_start_stk[mnum];\\r
+ stk->u.mem.prev_end = mem_end_stk[mnum];\\r
+ mem_start_stk[mnum] = GET_STACK_INDEX(stk);\\r
+ mem_end_stk[mnum] = INVALID_STACK_INDEX;\\r
STACK_INC;\\r
} while(0)\r
\r
#define STACK_PUSH_MEM_END(mnum, s) do {\\r
STACK_ENSURE(1);\\r
stk->type = STK_MEM_END;\\r
- stk->u.mem.num = (mnum);\\r
- stk->u.mem.pstr = (s);\\r
- stk->u.mem.start = mem_start_stk[mnum];\\r
- stk->u.mem.end = mem_end_stk[mnum];\\r
+ stk->zid = (mnum);\\r
+ stk->u.mem.pstr = (s);\\r
+ stk->u.mem.prev_start = mem_start_stk[mnum];\\r
+ stk->u.mem.prev_end = mem_end_stk[mnum];\\r
mem_end_stk[mnum] = GET_STACK_INDEX(stk);\\r
STACK_INC;\\r
} while(0)\r
#define STACK_PUSH_MEM_END_MARK(mnum) do {\\r
STACK_ENSURE(1);\\r
stk->type = STK_MEM_END_MARK;\\r
- stk->u.mem.num = (mnum);\\r
+ stk->zid = (mnum);\\r
STACK_INC;\\r
} while(0)\r
\r
while (k > stk_base) {\\r
k--;\\r
if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \\r
- && k->u.mem.num == (mnum)) {\\r
+ && k->zid == (mnum)) {\\r
level++;\\r
}\\r
- else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\\r
+ else if (k->type == STK_MEM_START && k->zid == (mnum)) {\\r
if (level == 0) break;\\r
level--;\\r
}\\r
}\\r
} while(0)\r
\r
-#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\\r
+#define STACK_PUSH_EMPTY_CHECK_START(cnum, s) do {\\r
STACK_ENSURE(1);\\r
- stk->type = STK_NULL_CHECK_START;\\r
- stk->u.null_check.num = (cnum);\\r
- stk->u.null_check.pstr = (s);\\r
+ stk->type = STK_EMPTY_CHECK_START;\\r
+ stk->zid = (cnum);\\r
+ stk->u.empty_check.pstr = (s);\\r
STACK_INC;\\r
} while(0)\r
\r
-#define STACK_PUSH_NULL_CHECK_END(cnum) do {\\r
+#define STACK_PUSH_EMPTY_CHECK_END(cnum) do {\\r
STACK_ENSURE(1);\\r
- stk->type = STK_NULL_CHECK_END;\\r
- stk->u.null_check.num = (cnum);\\r
+ stk->type = STK_EMPTY_CHECK_END;\\r
+ stk->zid = (cnum);\\r
STACK_INC;\\r
} while(0)\r
\r
STACK_INC;\\r
} while(0)\r
\r
+#define STACK_PUSH_SAVE_VAL(sid, stype, sval) do {\\r
+ STACK_ENSURE(1);\\r
+ stk->type = STK_SAVE_VAL;\\r
+ stk->zid = (sid);\\r
+ stk->u.val.type = (stype);\\r
+ stk->u.val.v = (UChar* )(sval);\\r
+ STACK_INC;\\r
+} while(0)\r
+\r
+#define STACK_PUSH_SAVE_VAL_WITH_SPREV(sid, stype, sval) do {\\r
+ STACK_ENSURE(1);\\r
+ stk->type = STK_SAVE_VAL;\\r
+ stk->zid = (sid);\\r
+ stk->u.val.type = (stype);\\r
+ stk->u.val.v = (UChar* )(sval);\\r
+ stk->u.val.v2 = sprev;\\r
+ STACK_INC;\\r
+} while(0)\r
+\r
+#define STACK_GET_SAVE_VAL_TYPE_LAST(stype, sval) do {\\r
+ StackType *k = stk;\\r
+ while (k > stk_base) {\\r
+ k--;\\r
+ STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST"); \\r
+ if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)) {\\r
+ (sval) = k->u.val.v;\\r
+ break;\\r
+ }\\r
+ }\\r
+} while (0)\r
+\r
+#define STACK_GET_SAVE_VAL_TYPE_LAST_ID(stype, sid, sval) do { \\r
+ int level = 0;\\r
+ StackType *k = stk;\\r
+ while (k > stk_base) {\\r
+ k--;\\r
+ STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID"); \\r
+ if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
+ && k->zid == (sid)) {\\r
+ if (level == 0) {\\r
+ (sval) = k->u.val.v;\\r
+ break;\\r
+ }\\r
+ }\\r
+ else if (k->type == STK_CALL_FRAME)\\r
+ level--;\\r
+ else if (k->type == STK_RETURN)\\r
+ level++;\\r
+ }\\r
+} while (0)\r
+\r
+#define STACK_GET_SAVE_VAL_TYPE_LAST_ID_WITH_SPREV(stype, sid, sval) do { \\r
+ int level = 0;\\r
+ StackType *k = stk;\\r
+ while (k > stk_base) {\\r
+ k--;\\r
+ STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID"); \\r
+ if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
+ && k->zid == (sid)) {\\r
+ if (level == 0) {\\r
+ (sval) = k->u.val.v;\\r
+ sprev = k->u.val.v2;\\r
+ break;\\r
+ }\\r
+ }\\r
+ else if (k->type == STK_CALL_FRAME)\\r
+ level--;\\r
+ else if (k->type == STK_RETURN)\\r
+ level++;\\r
+ }\\r
+} while (0)\r
+\r
+#define STACK_GET_SAVE_VAL_TYPE_LAST_ID_FROM(stype, sid, sval, stk_from) do { \\r
+ int level = 0;\\r
+ StackType *k = (stk_from);\\r
+ while (k > stk_base) {\\r
+ STACK_BASE_CHECK(k, "STACK_GET_SAVE_VAL_TYPE_LAST_ID_FROM"); \\r
+ if (k->type == STK_SAVE_VAL && k->u.val.type == (stype)\\r
+ && k->u.val.id == (sid)) {\\r
+ if (level == 0) {\\r
+ (sval) = k->u.val.v;\\r
+ break;\\r
+ }\\r
+ }\\r
+ else if (k->type == STK_CALL_FRAME)\\r
+ level--;\\r
+ else if (k->type == STK_RETURN)\\r
+ level++;\\r
+ k--;\\r
+ }\\r
+} while (0)\r
+\r
+#define STACK_PUSH_CALLOUT_CONTENTS(anum, func) do {\\r
+ STACK_ENSURE(1);\\r
+ stk->type = STK_CALLOUT;\\r
+ stk->zid = ONIG_NON_NAME_ID;\\r
+ stk->u.callout.num = (anum);\\r
+ stk->u.callout.func = (func);\\r
+ STACK_INC;\\r
+} while(0)\r
+\r
+#define STACK_PUSH_CALLOUT_NAME(aid, anum, func) do {\\r
+ STACK_ENSURE(1);\\r
+ stk->type = STK_CALLOUT;\\r
+ stk->zid = (aid);\\r
+ stk->u.callout.num = (anum);\\r
+ stk->u.callout.func = (func);\\r
+ STACK_INC;\\r
+} while(0)\r
\r
#ifdef ONIG_DEBUG\r
#define STACK_BASE_CHECK(p, at) \\r
STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \\r
} while(0)\r
\r
+\r
+#ifdef USE_CALLOUT\r
+#define POP_CALLOUT_CASE \\r
+ else if (stk->type == STK_CALLOUT) {\\r
+ RETRACTION_CALLOUT(stk->u.callout.func, stk->zid, stk->u.callout.num, msa->mp->callout_user_data);\\r
+ }\r
+#else\r
+#define POP_CALLOUT_CASE\r
+#endif\r
+\r
#define STACK_POP do {\\r
switch (pop_level) {\\r
case STACK_POP_LEVEL_FREE:\\r
stk--;\\r
STACK_BASE_CHECK(stk, "STACK_POP"); \\r
if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
- ELSE_IF_STATE_CHECK_MARK(stk);\\r
}\\r
break;\\r
case STACK_POP_LEVEL_MEM_START:\\r
STACK_BASE_CHECK(stk, "STACK_POP 2"); \\r
if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
else if (stk->type == STK_MEM_START) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
+ mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
+ mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
}\\r
- ELSE_IF_STATE_CHECK_MARK(stk);\\r
}\\r
break;\\r
default:\\r
stk--;\\r
STACK_BASE_CHECK(stk, "STACK_POP 3"); \\r
if ((stk->type & STK_MASK_POP_USED) != 0) break;\\r
- else if (stk->type == STK_MEM_START) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
- }\\r
- else if (stk->type == STK_REPEAT_INC) {\\r
- STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
- }\\r
- else if (stk->type == STK_MEM_END) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
+ else if ((stk->type & STK_MASK_POP_HANDLED) != 0) {\\r
+ if (stk->type == STK_MEM_START) {\\r
+ mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
+ mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
+ }\\r
+ else if (stk->type == STK_REPEAT_INC) {\\r
+ STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
+ }\\r
+ else if (stk->type == STK_MEM_END) {\\r
+ mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
+ mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
+ }\\r
+ POP_CALLOUT_CASE\\r
}\\r
- ELSE_IF_STATE_CHECK_MARK(stk);\\r
}\\r
break;\\r
}\\r
} while(0)\r
\r
-#define STACK_POP_TIL_POS_NOT do {\\r
+#define POP_TIL_BODY(aname, til_type) do {\\r
while (1) {\\r
stk--;\\r
- STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \\r
- if (stk->type == STK_POS_NOT) break;\\r
- else if (stk->type == STK_MEM_START) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
- }\\r
- else if (stk->type == STK_REPEAT_INC) {\\r
- STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
- }\\r
- else if (stk->type == STK_MEM_END) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
+ STACK_BASE_CHECK(stk, (aname));\\r
+ if ((stk->type & STK_MASK_POP_HANDLED_TIL) != 0) {\\r
+ if (stk->type == (til_type)) break;\\r
+ else {\\r
+ if (stk->type == STK_MEM_START) {\\r
+ mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
+ mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
+ }\\r
+ else if (stk->type == STK_REPEAT_INC) {\\r
+ STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
+ }\\r
+ else if (stk->type == STK_MEM_END) {\\r
+ mem_start_stk[stk->zid] = stk->u.mem.prev_start;\\r
+ mem_end_stk[stk->zid] = stk->u.mem.prev_end;\\r
+ }\\r
+ /* Don't call callout here because negation of total success by (?!..) (?<!..) */\\r
+ }\\r
}\\r
- ELSE_IF_STATE_CHECK_MARK(stk);\\r
}\\r
} while(0)\r
\r
-#define STACK_POP_TIL_LOOK_BEHIND_NOT do {\\r
- while (1) {\\r
- stk--;\\r
- STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \\r
- if (stk->type == STK_LOOK_BEHIND_NOT) break;\\r
- else if (stk->type == STK_MEM_START) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
- }\\r
- else if (stk->type == STK_REPEAT_INC) {\\r
- STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\\r
- }\\r
- else if (stk->type == STK_MEM_END) {\\r
- mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\\r
- mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\\r
- }\\r
- ELSE_IF_STATE_CHECK_MARK(stk);\\r
- }\\r
+#define STACK_POP_TIL_ALT_PREC_READ_NOT do {\\r
+ POP_TIL_BODY("STACK_POP_TIL_ALT_PREC_READ_NOT", STK_ALT_PREC_READ_NOT);\\r
} while(0)\r
\r
-#define STACK_POS_END(k) do {\\r
+#define STACK_POP_TIL_ALT_LOOK_BEHIND_NOT do {\\r
+ POP_TIL_BODY("STACK_POP_TIL_ALT_LOOK_BEHIND_NOT", STK_ALT_LOOK_BEHIND_NOT);\\r
+} while(0)\r
+\r
+\r
+#define STACK_EXEC_TO_VOID(k) do {\\r
k = stk;\\r
while (1) {\\r
k--;\\r
- STACK_BASE_CHECK(k, "STACK_POS_END"); \\r
+ STACK_BASE_CHECK(k, "STACK_EXEC_TO_VOID"); \\r
if (IS_TO_VOID_TARGET(k)) {\\r
+ if (k->type == STK_TO_VOID_START) {\\r
+ k->type = STK_VOID;\\r
+ break;\\r
+ }\\r
k->type = STK_VOID;\\r
}\\r
- else if (k->type == STK_POS) {\\r
- k->type = STK_VOID;\\r
- break;\\r
- }\\r
- }\\r
-} while(0)\r
-\r
-#define STACK_STOP_BT_END do {\\r
- OnigStackType *k = stk;\\r
- while (1) {\\r
- k--;\\r
- STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \\r
- if (IS_TO_VOID_TARGET(k)) {\\r
- k->type = STK_VOID;\\r
- }\\r
- else if (k->type == STK_STOP_BT) {\\r
- k->type = STK_VOID;\\r
- break;\\r
- }\\r
}\\r
} while(0)\r
\r
-#define STACK_NULL_CHECK(isnull,id,s) do {\\r
- OnigStackType* k = stk;\\r
+#define STACK_EMPTY_CHECK(isnull,sid,s) do {\\r
+ StackType* k = stk;\\r
while (1) {\\r
k--;\\r
- STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \\r
- if (k->type == STK_NULL_CHECK_START) {\\r
- if (k->u.null_check.num == (id)) {\\r
- (isnull) = (k->u.null_check.pstr == (s));\\r
+ STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK"); \\r
+ if (k->type == STK_EMPTY_CHECK_START) {\\r
+ if (k->zid == (sid)) {\\r
+ (isnull) = (k->u.empty_check.pstr == (s));\\r
break;\\r
}\\r
}\\r
}\\r
} while(0)\r
\r
-#define STACK_NULL_CHECK_REC(isnull,id,s) do {\\r
- int level = 0;\\r
- OnigStackType* k = stk;\\r
- while (1) {\\r
- k--;\\r
- STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \\r
- if (k->type == STK_NULL_CHECK_START) {\\r
- if (k->u.null_check.num == (id)) {\\r
- if (level == 0) {\\r
- (isnull) = (k->u.null_check.pstr == (s));\\r
- break;\\r
- }\\r
- else level--;\\r
- }\\r
- }\\r
- else if (k->type == STK_NULL_CHECK_END) {\\r
- level++;\\r
- }\\r
+#define STACK_MEM_START_GET_PREV_END_ADDR(k /* STK_MEM_START*/, reg, addr) do {\\r
+ if (k->u.mem.prev_end == INVALID_STACK_INDEX) {\\r
+ (addr) = 0;\\r
}\\r
-} while(0)\r
+ else {\\r
+ if (MEM_STATUS_AT((reg)->bt_mem_end, k->zid))\\r
+ (addr) = STACK_AT(k->u.mem.prev_end)->u.mem.pstr;\\r
+ else\\r
+ (addr) = (UChar* )k->u.mem.prev_end;\\r
+ }\\r
+} while (0)\r
\r
-#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\\r
- OnigStackType* k = stk;\\r
+#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
+#define STACK_EMPTY_CHECK_MEM(isnull,sid,s,reg) do {\\r
+ StackType* k = stk;\\r
while (1) {\\r
k--;\\r
- STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \\r
- if (k->type == STK_NULL_CHECK_START) {\\r
- if (k->u.null_check.num == (id)) {\\r
- if (k->u.null_check.pstr != (s)) {\\r
+ STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_MEM"); \\r
+ if (k->type == STK_EMPTY_CHECK_START) {\\r
+ if (k->zid == (sid)) {\\r
+ if (k->u.empty_check.pstr != (s)) {\\r
(isnull) = 0;\\r
break;\\r
}\\r
(isnull) = 1;\\r
while (k < stk) {\\r
if (k->type == STK_MEM_START) {\\r
- if (k->u.mem.end == INVALID_STACK_INDEX) {\\r
+ STACK_MEM_START_GET_PREV_END_ADDR(k, reg, endp);\\r
+ if (endp == 0) {\\r
(isnull) = 0; break;\\r
}\\r
- if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\\r
- endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\\r
- else\\r
- endp = (UChar* )k->u.mem.end;\\r
- if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\\r
+ else if (STACK_AT(k->u.mem.prev_start)->u.mem.pstr != endp) {\\r
(isnull) = 0; break;\\r
}\\r
else if (endp != s) {\\r
}\\r
k++;\\r
}\\r
- break;\\r
+ break;\\r
}\\r
}\\r
}\\r
}\\r
} while(0)\r
\r
-#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\\r
+#define STACK_EMPTY_CHECK_MEM_REC(isnull,sid,s,reg) do {\\r
int level = 0;\\r
- OnigStackType* k = stk;\\r
+ StackType* k = stk;\\r
while (1) {\\r
k--;\\r
- STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \\r
- if (k->type == STK_NULL_CHECK_START) {\\r
- if (k->u.null_check.num == (id)) {\\r
+ STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_MEM_REC");\\r
+ if (k->type == STK_EMPTY_CHECK_START) {\\r
+ if (k->zid == (sid)) {\\r
if (level == 0) {\\r
- if (k->u.null_check.pstr != (s)) {\\r
+ if (k->u.empty_check.pstr != (s)) {\\r
(isnull) = 0;\\r
break;\\r
}\\r
(isnull) = 1;\\r
while (k < stk) {\\r
if (k->type == STK_MEM_START) {\\r
- if (k->u.mem.end == INVALID_STACK_INDEX) {\\r
- (isnull) = 0; break;\\r
- }\\r
- if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\\r
- endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\\r
- else\\r
- endp = (UChar* )k->u.mem.end;\\r
- if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\\r
- (isnull) = 0; break;\\r
- }\\r
- else if (endp != s) {\\r
- (isnull) = -1; /* empty, but position changed */ \\r
+ if (level == 0) {\\r
+ STACK_MEM_START_GET_PREV_END_ADDR(k, reg, endp);\\r
+ if (endp == 0) {\\r
+ (isnull) = 0; break;\\r
+ }\\r
+ else if (STACK_AT(k->u.mem.prev_start)->u.mem.pstr != endp) { \\r
+ (isnull) = 0; break;\\r
+ }\\r
+ else if (endp != s) {\\r
+ (isnull) = -1; /* empty, but position changed */\\r
+ }\\r
}\\r
}\\r
+ else if (k->type == STK_EMPTY_CHECK_START) {\\r
+ if (k->zid == (sid)) level++;\\r
+ }\\r
+ else if (k->type == STK_EMPTY_CHECK_END) {\\r
+ if (k->zid == (sid)) level--;\\r
+ }\\r
k++;\\r
}\\r
- break;\\r
+ break;\\r
}\\r
}\\r
else {\\r
}\\r
}\\r
}\\r
- else if (k->type == STK_NULL_CHECK_END) {\\r
- if (k->u.null_check.num == (id)) level++;\\r
+ else if (k->type == STK_EMPTY_CHECK_END) {\\r
+ if (k->zid == (sid)) level++;\\r
+ }\\r
+ }\\r
+} while(0)\r
+#else\r
+#define STACK_EMPTY_CHECK_REC(isnull,id,s) do {\\r
+ int level = 0;\\r
+ StackType* k = stk;\\r
+ while (1) {\\r
+ k--;\\r
+ STACK_BASE_CHECK(k, "STACK_EMPTY_CHECK_REC"); \\r
+ if (k->type == STK_EMPTY_CHECK_START) {\\r
+ if (k->u.empty_check.num == (id)) {\\r
+ if (level == 0) {\\r
+ (isnull) = (k->u.empty_check.pstr == (s));\\r
+ break;\\r
+ }\\r
+ }\\r
+ level--;\\r
+ }\\r
+ else if (k->type == STK_EMPTY_CHECK_END) {\\r
+ level++;\\r
}\\r
}\\r
} while(0)\r
+#endif /* USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT */\r
\r
-#define STACK_GET_REPEAT(id, k) do {\\r
+#define STACK_GET_REPEAT(sid, k) do {\\r
int level = 0;\\r
k = stk;\\r
while (1) {\\r
STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \\r
if (k->type == STK_REPEAT) {\\r
if (level == 0) {\\r
- if (k->u.repeat.num == (id)) {\\r
+ if (k->zid == (sid)) {\\r
break;\\r
}\\r
}\\r
\r
#define STACK_RETURN(addr) do {\\r
int level = 0;\\r
- OnigStackType* k = stk;\\r
+ StackType* k = stk;\\r
while (1) {\\r
k--;\\r
STACK_BASE_CHECK(k, "STACK_RETURN"); \\r
} while(0)\r
\r
static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,\r
- UChar* s1, UChar** ps2, int mblen)\r
+ UChar* s1, UChar** ps2, int mblen)\r
{\r
UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
\r
\r
#define IS_EMPTY_STR (str == end)\r
-#define ON_STR_BEGIN(s) ((s) == str)\r
-#define ON_STR_END(s) ((s) == end)\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
+#define ON_STR_BEGIN(s) ((s) == str)\r
+#define ON_STR_END(s) ((s) == end)\r
#define DATA_ENSURE_CHECK1 (s < right_range)\r
#define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)\r
#define DATA_ENSURE(n) if (s + (n) > right_range) goto fail\r
-#else\r
-#define DATA_ENSURE_CHECK1 (s < end)\r
-#define DATA_ENSURE_CHECK(n) (s + (n) <= end)\r
-#define DATA_ENSURE(n) if (s + (n) > end) goto fail\r
-#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */\r
\r
+#define INIT_RIGHT_RANGE right_range = (UChar* )in_right_range\r
\r
#ifdef USE_CAPTURE_HISTORY\r
static int\r
-make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,\r
- OnigStackType* stk_top, UChar* str, regex_t* reg)\r
+make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,\r
+ StackType* stk_top, UChar* str, regex_t* reg)\r
{\r
int n, r;\r
OnigCaptureTreeNode* child;\r
- OnigStackType* k = *kp;\r
+ StackType* k = *kp;\r
\r
while (k < stk_top) {\r
if (k->type == STK_MEM_START) {\r
- n = k->u.mem.num;\r
+ n = k->zid;\r
if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&\r
- BIT_STATUS_AT(reg->capture_history, n) != 0) {\r
+ MEM_STATUS_AT(reg->capture_history, n) != 0) {\r
child = history_node_new();\r
CHECK_NULL_RETURN_MEMERR(child);\r
child->group = n;\r
}\r
}\r
else if (k->type == STK_MEM_END) {\r
- if (k->u.mem.num == node->group) {\r
+ if (k->zid == node->group) {\r
node->end = (int )(k->u.mem.pstr - str);\r
*kp = k;\r
return 0;\r
return 0;\r
}\r
\r
-static int backref_match_at_nested_level(regex_t* reg\r
- , OnigStackType* top, OnigStackType* stk_base\r
- , int ignore_case, int case_fold_flag\r
- , int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)\r
+static int\r
+backref_match_at_nested_level(regex_t* reg,\r
+ StackType* top, StackType* stk_base,\r
+ int ignore_case, int case_fold_flag,\r
+ int nest, int mem_num, UChar* memp,\r
+ UChar** s, const UChar* send)\r
{\r
UChar *ss, *p, *pstart, *pend = NULL_UCHARP;\r
int level;\r
- OnigStackType* k;\r
+ StackType* k;\r
\r
level = 0;\r
k = top;\r
}\r
else if (level == nest) {\r
if (k->type == STK_MEM_START) {\r
- if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {\r
- pstart = k->u.mem.pstr;\r
- if (pend != NULL_UCHARP) {\r
- if (pend - pstart > send - *s) return 0; /* or goto next_mem; */\r
- p = pstart;\r
- ss = *s;\r
-\r
- if (ignore_case != 0) {\r
- if (string_cmp_ic(reg->enc, case_fold_flag,\r
- pstart, &ss, (int )(pend - pstart)) == 0)\r
- return 0; /* or goto next_mem; */\r
- }\r
- else {\r
- while (p < pend) {\r
- if (*p++ != *ss++) return 0; /* or goto next_mem; */\r
- }\r
- }\r
-\r
- *s = ss;\r
- return 1;\r
- }\r
- }\r
+ if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
+ pstart = k->u.mem.pstr;\r
+ if (IS_NOT_NULL(pend)) {\r
+ if (pend - pstart > send - *s) return 0; /* or goto next_mem; */\r
+ p = pstart;\r
+ ss = *s;\r
+\r
+ if (ignore_case != 0) {\r
+ if (string_cmp_ic(reg->enc, case_fold_flag,\r
+ pstart, &ss, (int )(pend - pstart)) == 0)\r
+ return 0; /* or goto next_mem; */\r
+ }\r
+ else {\r
+ while (p < pend) {\r
+ if (*p++ != *ss++) return 0; /* or goto next_mem; */\r
+ }\r
+ }\r
+\r
+ *s = ss;\r
+ return 1;\r
+ }\r
+ }\r
}\r
else if (k->type == STK_MEM_END) {\r
- if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {\r
- pend = k->u.mem.pstr;\r
- }\r
+ if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
+ pend = k->u.mem.pstr;\r
+ }\r
+ }\r
+ }\r
+ k--;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+static int\r
+backref_check_at_nested_level(regex_t* reg,\r
+ StackType* top, StackType* stk_base,\r
+ int nest, int mem_num, UChar* memp)\r
+{\r
+ int level;\r
+ StackType* k;\r
+\r
+ level = 0;\r
+ k = top;\r
+ k--;\r
+ while (k >= stk_base) {\r
+ if (k->type == STK_CALL_FRAME) {\r
+ level--;\r
+ }\r
+ else if (k->type == STK_RETURN) {\r
+ level++;\r
+ }\r
+ else if (level == nest) {\r
+ if (k->type == STK_MEM_END) {\r
+ if (mem_is_in_memp(k->zid, mem_num, memp)) {\r
+ return 1;\r
+ }\r
}\r
}\r
k--;\r
static int OpPrevTarget = OP_FAIL;\r
static int MaxStackDepth = 0;\r
\r
-#define MOP_IN(opcode) do {\\r
+#define SOP_IN(opcode) do {\\r
if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\\r
OpCurr = opcode;\\r
OpCounter[opcode]++;\\r
GETTIME(ts);\\r
} while(0)\r
\r
-#define MOP_OUT do {\\r
+#define SOP_OUT do {\\r
GETTIME(te);\\r
OpTime[OpCurr] += TIMEDIFF(te, ts);\\r
} while(0)\r
MaxStackDepth = 0;\r
}\r
\r
-extern void\r
+extern int\r
onig_print_statistics(FILE* f)\r
{\r
+ int r;\r
int i;\r
- fprintf(f, " count prev time\n");\r
- for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {\r
- fprintf(f, "%8d: %8d: %10ld: %s\n",\r
- OpCounter[i], OpPrevCounter[i], OpTime[i], OnigOpInfo[i].name);\r
+\r
+ r = fprintf(f, " count prev time\n");\r
+ if (r < 0) return -1;\r
+\r
+ for (i = 0; OpInfo[i].opcode >= 0; i++) {\r
+ r = fprintf(f, "%8d: %8d: %10ld: %s\n",\r
+ OpCounter[i], OpPrevCounter[i], OpTime[i], OpInfo[i].name);\r
+ if (r < 0) return -1;\r
}\r
- fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);\r
+ r = fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);\r
+ if (r < 0) return -1;\r
+\r
+ return 0;\r
}\r
\r
#define STACK_INC do {\\r
#else\r
#define STACK_INC stk++\r
\r
-#define MOP_IN(opcode)\r
-#define MOP_OUT\r
+#define SOP_IN(opcode)\r
+#define SOP_OUT\r
#endif\r
\r
\r
/* if sstart == str then set sprev to NULL. */\r
static int\r
match_at(regex_t* reg, const UChar* str, const UChar* end,\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
- const UChar* right_range,\r
-#endif\r
- const UChar* sstart, UChar* sprev, OnigMatchArg* msa)\r
+ const UChar* in_right_range, const UChar* sstart, UChar* sprev,\r
+ MatchArg* msa)\r
{\r
static UChar FinishCode[] = { OP_FINISH };\r
\r
LengthType tlen, tlen2;\r
MemNumType mem;\r
RelAddrType addr;\r
+ UChar *s, *q, *sbegin;\r
+ UChar *right_range;\r
+ int is_alloca;\r
+ char *alloc_base;\r
+ StackType *stk_base, *stk, *stk_end;\r
+ StackType *stkp; /* used as any purpose. */\r
+ StackIndex si;\r
+ StackIndex *repeat_stk;\r
+ StackIndex *mem_start_stk, *mem_end_stk;\r
+ UChar* keep;\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ unsigned long retry_limit_in_match;\r
+ unsigned long retry_in_match_counter;\r
+#endif\r
+\r
+#ifdef USE_CALLOUT\r
+ int of;\r
+#endif\r
+\r
+ UChar *p = reg->p;\r
OnigOptionType option = reg->options;\r
OnigEncoding encode = reg->enc;\r
OnigCaseFoldType case_fold_flag = reg->case_fold_flag;\r
- UChar *s, *q, *sbegin;\r
- UChar *p = reg->p;\r
- char *alloca_base;\r
- OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;\r
- OnigStackType *stkp; /* used as any purpose. */\r
- OnigStackIndex si;\r
- OnigStackIndex *repeat_stk;\r
- OnigStackIndex *mem_start_stk, *mem_end_stk;\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- int scv;\r
- unsigned char* state_check_buff = msa->state_check_buff;\r
- int num_comb_exp_check = reg->num_comb_exp_check;\r
-#endif\r
- n = reg->num_repeat + reg->num_mem * 2;\r
-\r
- STACK_INIT(alloca_base, n, INIT_MATCH_STACK_SIZE);\r
+\r
+#ifdef USE_CALLOUT\r
+ msa->mp->match_at_call_counter++;\r
+#endif\r
+\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ retry_limit_in_match = msa->retry_limit_in_match;\r
+#endif\r
+\r
pop_level = reg->stack_pop_level;\r
num_mem = reg->num_mem;\r
- repeat_stk = (OnigStackIndex* )alloca_base;\r
-\r
- mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);\r
- mem_end_stk = mem_start_stk + num_mem;\r
- mem_start_stk--; /* for index start from 1,\r
- mem_start_stk[1]..mem_start_stk[num_mem] */\r
- mem_end_stk--; /* for index start from 1,\r
- mem_end_stk[1]..mem_end_stk[num_mem] */\r
+ STACK_INIT(INIT_MATCH_STACK_SIZE);\r
+ UPDATE_FOR_STACK_REALLOC;\r
for (i = 1; i <= num_mem; i++) {\r
mem_start_stk[i] = mem_end_stk[i] = INVALID_STACK_INDEX;\r
}\r
\r
#ifdef ONIG_DEBUG_MATCH\r
- fprintf(stderr, "match_at: str: %d, end: %d, start: %d, sprev: %d\n",\r
- (int )str, (int )end, (int )sstart, (int )sprev);\r
+ fprintf(stderr, "match_at: str: %p, end: %p, start: %p, sprev: %p\n",\r
+ str, end, sstart, sprev);\r
fprintf(stderr, "size: %d, start offset: %d\n",\r
- (int )(end - str), (int )(sstart - str));\r
+ (int )(end - str), (int )(sstart - str));\r
#endif\r
\r
- STACK_PUSH_ENSURED(STK_ALT, FinishCode); /* bottom stack */\r
best_len = ONIG_MISMATCH;\r
- s = (UChar* )sstart;\r
+ keep = s = (UChar* )sstart;\r
+ STACK_PUSH_BOTTOM(STK_ALT, FinishCode); /* bottom stack */\r
+ INIT_RIGHT_RANGE;\r
+\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ retry_in_match_counter = 0;\r
+#endif\r
+\r
while (1) {\r
#ifdef ONIG_DEBUG_MATCH\r
{\r
+ static unsigned int counter = 1;\r
+\r
UChar *q, *bp, buf[50];\r
int len;\r
- fprintf(stderr, "%4d> \"", (int )(s - str));\r
+ fprintf(stderr, "%7u: %7ld: %4d> \"",\r
+ counter, GET_STACK_INDEX(stk), (int )(s - str));\r
+ counter++;\r
+\r
bp = buf;\r
for (i = 0, q = s; i < 7 && q < end; i++) {\r
- len = enclen(encode, q);\r
- while (len-- > 0) *bp++ = *q++;\r
+ len = enclen(encode, q);\r
+ while (len-- > 0) *bp++ = *q++;\r
}\r
if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }\r
else { xmemcpy(bp, "\"", 1); bp += 1; }\r
*bp = 0;\r
fputs((char* )buf, stderr);\r
+\r
for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);\r
- onig_print_compiled_byte_code(stderr, p, NULL, encode);\r
+ if (p == FinishCode)\r
+ fprintf(stderr, "----: ");\r
+ else\r
+ fprintf(stderr, "%4d: ", (int )(p - reg->p));\r
+ onig_print_compiled_byte_code(stderr, p, NULL, reg->p, encode);\r
fprintf(stderr, "\n");\r
}\r
#endif\r
\r
sbegin = s;\r
switch (*p++) {\r
- case OP_END: MOP_IN(OP_END);\r
- n = (int)(s - sstart);\r
+ case OP_END: SOP_IN(OP_END);\r
+ n = (int )(s - sstart);\r
if (n > best_len) {\r
- OnigRegion* region;\r
+ OnigRegion* region;\r
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
- if (IS_FIND_LONGEST(option)) {\r
- if (n > msa->best_len) {\r
- msa->best_len = n;\r
- msa->best_s = (UChar* )sstart;\r
- }\r
- else\r
- goto end_best_len;\r
+ if (IS_FIND_LONGEST(option)) {\r
+ if (n > msa->best_len) {\r
+ msa->best_len = n;\r
+ msa->best_s = (UChar* )sstart;\r
+ }\r
+ else\r
+ goto end_best_len;\r
}\r
#endif\r
- best_len = n;\r
- region = msa->region;\r
- if (region) {\r
+ best_len = n;\r
+ region = msa->region;\r
+ if (region) {\r
+ if (keep > s) keep = s;\r
+\r
#ifdef USE_POSIX_API_REGION_OPTION\r
- if (IS_POSIX_REGION(msa->options)) {\r
- posix_regmatch_t* rmt = (posix_regmatch_t* )region;\r
-\r
- rmt[0].rm_so = (regoff_t)(sstart - str);\r
- rmt[0].rm_eo = (regoff_t)(s - str);\r
- for (i = 1; i <= num_mem; i++) {\r
- if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
- if (BIT_STATUS_AT(reg->bt_mem_start, i))\r
- rmt[i].rm_so = (regoff_t)(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
- else\r
- rmt[i].rm_so = (regoff_t)((UChar* )((void* )(mem_start_stk[i])) - str);\r
-\r
- rmt[i].rm_eo = (regoff_t)((BIT_STATUS_AT(reg->bt_mem_end, i)\r
- ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[i])) - str);\r
- }\r
- else {\r
- rmt[i].rm_so = rmt[i].rm_eo = ONIG_REGION_NOTPOS;\r
- }\r
- }\r
- }\r
- else {\r
+ if (IS_POSIX_REGION(msa->options)) {\r
+ posix_regmatch_t* rmt = (posix_regmatch_t* )region;\r
+\r
+ rmt[0].rm_so = (regoff_t )(keep - str);\r
+ rmt[0].rm_eo = (regoff_t )(s - str);\r
+ for (i = 1; i <= num_mem; i++) {\r
+ if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
+ rmt[i].rm_so = (regoff_t )(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
+ else\r
+ rmt[i].rm_so = (regoff_t )((UChar* )((void* )(mem_start_stk[i])) - str);\r
+\r
+ rmt[i].rm_eo = (regoff_t )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
+ ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[i]))\r
+ - str);\r
+ }\r
+ else {\r
+ rmt[i].rm_so = rmt[i].rm_eo = ONIG_REGION_NOTPOS;\r
+ }\r
+ }\r
+ }\r
+ else {\r
#endif /* USE_POSIX_API_REGION_OPTION */\r
- region->beg[0] = (int)(sstart - str);\r
- region->end[0] = (int)(s - str);\r
- for (i = 1; i <= num_mem; i++) {\r
- if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
- if (BIT_STATUS_AT(reg->bt_mem_start, i))\r
- region->beg[i] = (int)(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
- else\r
- region->beg[i] = (int)((UChar* )((void* )mem_start_stk[i]) - str);\r
-\r
- region->end[i] = (int)((BIT_STATUS_AT(reg->bt_mem_end, i)\r
- ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[i])) - str);\r
- }\r
- else {\r
- region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;\r
- }\r
- }\r
+ region->beg[0] = (int )(keep - str);\r
+ region->end[0] = (int )(s - str);\r
+ for (i = 1; i <= num_mem; i++) {\r
+ if (mem_end_stk[i] != INVALID_STACK_INDEX) {\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
+ region->beg[i] = (int )(STACK_AT(mem_start_stk[i])->u.mem.pstr - str);\r
+ else\r
+ region->beg[i] = (int )((UChar* )((void* )mem_start_stk[i]) - str);\r
+\r
+ region->end[i] = (int )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
+ ? STACK_AT(mem_end_stk[i])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[i])) - str);\r
+ }\r
+ else {\r
+ region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;\r
+ }\r
+ }\r
\r
#ifdef USE_CAPTURE_HISTORY\r
- if (reg->capture_history != 0) {\r
+ if (reg->capture_history != 0) {\r
int r;\r
OnigCaptureTreeNode* node;\r
\r
}\r
\r
node->group = 0;\r
- node->beg = (int)(sstart - str);\r
- node->end = (int)(s - str);\r
+ node->beg = (int )(keep - str);\r
+ node->end = (int )(s - str);\r
\r
stkp = stk_base;\r
r = make_capture_history_tree(region->history_root, &stkp,\r
best_len = r; /* error code */\r
goto finish;\r
}\r
- }\r
+ }\r
#endif /* USE_CAPTURE_HISTORY */\r
#ifdef USE_POSIX_API_REGION_OPTION\r
- } /* else IS_POSIX_REGION() */\r
+ } /* else IS_POSIX_REGION() */\r
#endif\r
- } /* if (region) */\r
+ } /* if (region) */\r
} /* n > best_len */\r
\r
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
end_best_len:\r
#endif\r
- MOP_OUT;\r
+ SOP_OUT;\r
\r
if (IS_FIND_CONDITION(option)) {\r
- if (IS_FIND_NOT_EMPTY(option) && s == sstart) {\r
- best_len = ONIG_MISMATCH;\r
- goto fail; /* for retry */\r
- }\r
- if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {\r
- goto fail; /* for retry */\r
- }\r
+ if (IS_FIND_NOT_EMPTY(option) && s == sstart) {\r
+ best_len = ONIG_MISMATCH;\r
+ goto fail; /* for retry */\r
+ }\r
+ if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {\r
+ goto fail; /* for retry */\r
+ }\r
}\r
\r
/* default behavior: return first-matching result. */\r
goto finish;\r
break;\r
\r
- case OP_EXACT1: MOP_IN(OP_EXACT1);\r
-#if 0\r
+ case OP_EXACT1: SOP_IN(OP_EXACT1);\r
DATA_ENSURE(1);\r
if (*p != *s) goto fail;\r
p++; s++;\r
-#endif\r
- if (*p != *s++) goto fail;\r
- DATA_ENSURE(0);\r
- p++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_EXACT1_IC: MOP_IN(OP_EXACT1_IC);\r
+ case OP_EXACT1_IC: SOP_IN(OP_EXACT1_IC);\r
{\r
- int len;\r
- UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
-\r
- DATA_ENSURE(1);\r
- len = ONIGENC_MBC_CASE_FOLD(encode,\r
- /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
- case_fold_flag,\r
- &s, end, lowbuf);\r
- DATA_ENSURE(0);\r
- q = lowbuf;\r
- while (len-- > 0) {\r
- if (*p != *q) {\r
+ int len;\r
+ UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
+\r
+ DATA_ENSURE(1);\r
+ len = ONIGENC_MBC_CASE_FOLD(encode,\r
+ /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
+ case_fold_flag,\r
+ &s, end, lowbuf);\r
+ DATA_ENSURE(0);\r
+ q = lowbuf;\r
+ while (len-- > 0) {\r
+ if (*p != *q) {\r
goto fail;\r
}\r
- p++; q++;\r
- }\r
+ p++; q++;\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_EXACT2: MOP_IN(OP_EXACT2);\r
+ case OP_EXACT2: SOP_IN(OP_EXACT2);\r
DATA_ENSURE(2);\r
if (*p != *s) goto fail;\r
p++; s++;\r
if (*p != *s) goto fail;\r
sprev = s;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACT3: MOP_IN(OP_EXACT3);\r
+ case OP_EXACT3: SOP_IN(OP_EXACT3);\r
DATA_ENSURE(3);\r
if (*p != *s) goto fail;\r
p++; s++;\r
if (*p != *s) goto fail;\r
sprev = s;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACT4: MOP_IN(OP_EXACT4);\r
+ case OP_EXACT4: SOP_IN(OP_EXACT4);\r
DATA_ENSURE(4);\r
if (*p != *s) goto fail;\r
p++; s++;\r
if (*p != *s) goto fail;\r
sprev = s;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACT5: MOP_IN(OP_EXACT5);\r
+ case OP_EXACT5: SOP_IN(OP_EXACT5);\r
DATA_ENSURE(5);\r
if (*p != *s) goto fail;\r
p++; s++;\r
if (*p != *s) goto fail;\r
sprev = s;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTN: MOP_IN(OP_EXACTN);\r
+ case OP_EXACTN: SOP_IN(OP_EXACTN);\r
GET_LENGTH_INC(tlen, p);\r
DATA_ENSURE(tlen);\r
while (tlen-- > 0) {\r
- if (*p++ != *s++) goto fail;\r
+ if (*p++ != *s++) goto fail;\r
}\r
sprev = s - 1;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTN_IC: MOP_IN(OP_EXACTN_IC);\r
+ case OP_EXACTN_IC: SOP_IN(OP_EXACTN_IC);\r
{\r
- int len;\r
- UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
-\r
- GET_LENGTH_INC(tlen, p);\r
- endp = p + tlen;\r
-\r
- while (p < endp) {\r
- sprev = s;\r
- DATA_ENSURE(1);\r
- len = ONIGENC_MBC_CASE_FOLD(encode,\r
- /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
- case_fold_flag,\r
- &s, end, lowbuf);\r
- DATA_ENSURE(0);\r
- q = lowbuf;\r
- while (len-- > 0) {\r
- if (*p != *q) goto fail;\r
- p++; q++;\r
- }\r
- }\r
- }\r
-\r
- MOP_OUT;\r
+ int len;\r
+ UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
+\r
+ GET_LENGTH_INC(tlen, p);\r
+ endp = p + tlen;\r
+\r
+ while (p < endp) {\r
+ sprev = s;\r
+ DATA_ENSURE(1);\r
+ len = ONIGENC_MBC_CASE_FOLD(encode,\r
+ /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */\r
+ case_fold_flag,\r
+ &s, end, lowbuf);\r
+ DATA_ENSURE(0);\r
+ q = lowbuf;\r
+ while (len-- > 0) {\r
+ if (*p != *q) goto fail;\r
+ p++; q++;\r
+ }\r
+ }\r
+ }\r
+\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTMB2N1: MOP_IN(OP_EXACTMB2N1);\r
+ case OP_EXACTMB2N1: SOP_IN(OP_EXACTMB2N1);\r
DATA_ENSURE(2);\r
if (*p != *s) goto fail;\r
p++; s++;\r
if (*p != *s) goto fail;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_EXACTMB2N2: MOP_IN(OP_EXACTMB2N2);\r
+ case OP_EXACTMB2N2: SOP_IN(OP_EXACTMB2N2);\r
DATA_ENSURE(4);\r
if (*p != *s) goto fail;\r
p++; s++;\r
p++; s++;\r
if (*p != *s) goto fail;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTMB2N3: MOP_IN(OP_EXACTMB2N3);\r
+ case OP_EXACTMB2N3: SOP_IN(OP_EXACTMB2N3);\r
DATA_ENSURE(6);\r
if (*p != *s) goto fail;\r
p++; s++;\r
p++; s++;\r
if (*p != *s) goto fail;\r
p++; s++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTMB2N: MOP_IN(OP_EXACTMB2N);\r
+ case OP_EXACTMB2N: SOP_IN(OP_EXACTMB2N);\r
GET_LENGTH_INC(tlen, p);\r
DATA_ENSURE(tlen * 2);\r
while (tlen-- > 0) {\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
}\r
sprev = s - 2;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTMB3N: MOP_IN(OP_EXACTMB3N);\r
+ case OP_EXACTMB3N: SOP_IN(OP_EXACTMB3N);\r
GET_LENGTH_INC(tlen, p);\r
DATA_ENSURE(tlen * 3);\r
while (tlen-- > 0) {\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
}\r
sprev = s - 3;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_EXACTMBN: MOP_IN(OP_EXACTMBN);\r
+ case OP_EXACTMBN: SOP_IN(OP_EXACTMBN);\r
GET_LENGTH_INC(tlen, p); /* mb-len */\r
GET_LENGTH_INC(tlen2, p); /* string len */\r
tlen2 *= tlen;\r
DATA_ENSURE(tlen2);\r
while (tlen2-- > 0) {\r
- if (*p != *s) goto fail;\r
- p++; s++;\r
+ if (*p != *s) goto fail;\r
+ p++; s++;\r
}\r
sprev = s - tlen;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_CCLASS: MOP_IN(OP_CCLASS);\r
+ case OP_CCLASS: SOP_IN(OP_CCLASS);\r
DATA_ENSURE(1);\r
if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;\r
p += SIZE_BITSET;\r
s += enclen(encode, s); /* OP_CCLASS can match mb-code. \D, \S */\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_MB: MOP_IN(OP_CCLASS_MB);\r
+ case OP_CCLASS_MB: SOP_IN(OP_CCLASS_MB);\r
if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;\r
\r
cclass_mb:\r
GET_LENGTH_INC(tlen, p);\r
{\r
- OnigCodePoint code;\r
- UChar *ss;\r
- int mb_len;\r
+ OnigCodePoint code;\r
+ UChar *ss;\r
+ int mb_len;\r
\r
- DATA_ENSURE(1);\r
- mb_len = enclen(encode, s);\r
- DATA_ENSURE(mb_len);\r
- ss = s;\r
- s += mb_len;\r
- code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
+ DATA_ENSURE(1);\r
+ mb_len = enclen(encode, s);\r
+ DATA_ENSURE(mb_len);\r
+ ss = s;\r
+ s += mb_len;\r
+ code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
\r
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS\r
- if (! onig_is_in_code_range(p, code)) goto fail;\r
+ if (! onig_is_in_code_range(p, code)) goto fail;\r
#else\r
- q = p;\r
- ALIGNMENT_RIGHT(q);\r
- if (! onig_is_in_code_range(q, code)) goto fail;\r
+ q = p;\r
+ ALIGNMENT_RIGHT(q);\r
+ if (! onig_is_in_code_range(q, code)) goto fail;\r
#endif\r
}\r
p += tlen;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_MIX: MOP_IN(OP_CCLASS_MIX);\r
+ case OP_CCLASS_MIX: SOP_IN(OP_CCLASS_MIX);\r
DATA_ENSURE(1);\r
if (ONIGENC_IS_MBC_HEAD(encode, s)) {\r
- p += SIZE_BITSET;\r
- goto cclass_mb;\r
+ p += SIZE_BITSET;\r
+ goto cclass_mb;\r
}\r
else {\r
- if (BITSET_AT(((BitSetRef )p), *s) == 0)\r
- goto fail;\r
+ if (BITSET_AT(((BitSetRef )p), *s) == 0)\r
+ goto fail;\r
\r
- p += SIZE_BITSET;\r
- GET_LENGTH_INC(tlen, p);\r
- p += tlen;\r
- s++;\r
+ p += SIZE_BITSET;\r
+ GET_LENGTH_INC(tlen, p);\r
+ p += tlen;\r
+ s++;\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_NOT: MOP_IN(OP_CCLASS_NOT);\r
+ case OP_CCLASS_NOT: SOP_IN(OP_CCLASS_NOT);\r
DATA_ENSURE(1);\r
if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;\r
p += SIZE_BITSET;\r
s += enclen(encode, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_MB_NOT: MOP_IN(OP_CCLASS_MB_NOT);\r
+ case OP_CCLASS_MB_NOT: SOP_IN(OP_CCLASS_MB_NOT);\r
DATA_ENSURE(1);\r
if (! ONIGENC_IS_MBC_HEAD(encode, s)) {\r
- s++;\r
- GET_LENGTH_INC(tlen, p);\r
- p += tlen;\r
- goto cc_mb_not_success;\r
+ s++;\r
+ GET_LENGTH_INC(tlen, p);\r
+ p += tlen;\r
+ goto cc_mb_not_success;\r
}\r
\r
cclass_mb_not:\r
GET_LENGTH_INC(tlen, p);\r
{\r
- OnigCodePoint code;\r
- UChar *ss;\r
- int mb_len = enclen(encode, s);\r
+ OnigCodePoint code;\r
+ UChar *ss;\r
+ int mb_len = enclen(encode, s);\r
\r
- if (! DATA_ENSURE_CHECK(mb_len)) {\r
+ if (! DATA_ENSURE_CHECK(mb_len)) {\r
DATA_ENSURE(1);\r
- s = (UChar* )end;\r
- p += tlen;\r
- goto cc_mb_not_success;\r
- }\r
+ s = (UChar* )end;\r
+ p += tlen;\r
+ goto cc_mb_not_success;\r
+ }\r
\r
- ss = s;\r
- s += mb_len;\r
- code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
+ ss = s;\r
+ s += mb_len;\r
+ code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
\r
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS\r
- if (onig_is_in_code_range(p, code)) goto fail;\r
+ if (onig_is_in_code_range(p, code)) goto fail;\r
#else\r
- q = p;\r
- ALIGNMENT_RIGHT(q);\r
- if (onig_is_in_code_range(q, code)) goto fail;\r
+ q = p;\r
+ ALIGNMENT_RIGHT(q);\r
+ if (onig_is_in_code_range(q, code)) goto fail;\r
#endif\r
}\r
p += tlen;\r
\r
cc_mb_not_success:\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_MIX_NOT: MOP_IN(OP_CCLASS_MIX_NOT);\r
+ case OP_CCLASS_MIX_NOT: SOP_IN(OP_CCLASS_MIX_NOT);\r
DATA_ENSURE(1);\r
if (ONIGENC_IS_MBC_HEAD(encode, s)) {\r
- p += SIZE_BITSET;\r
- goto cclass_mb_not;\r
+ p += SIZE_BITSET;\r
+ goto cclass_mb_not;\r
}\r
else {\r
- if (BITSET_AT(((BitSetRef )p), *s) != 0)\r
- goto fail;\r
+ if (BITSET_AT(((BitSetRef )p), *s) != 0)\r
+ goto fail;\r
\r
- p += SIZE_BITSET;\r
- GET_LENGTH_INC(tlen, p);\r
- p += tlen;\r
- s++;\r
+ p += SIZE_BITSET;\r
+ GET_LENGTH_INC(tlen, p);\r
+ p += tlen;\r
+ s++;\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_CCLASS_NODE: MOP_IN(OP_CCLASS_NODE);\r
+#ifdef USE_OP_CCLASS_NODE\r
+ case OP_CCLASS_NODE: SOP_IN(OP_CCLASS_NODE);\r
{\r
- OnigCodePoint code;\r
+ OnigCodePoint code;\r
void *node;\r
int mb_len;\r
UChar *ss;\r
\r
DATA_ENSURE(1);\r
GET_POINTER_INC(node, p);\r
- mb_len = enclen(encode, s);\r
- ss = s;\r
- s += mb_len;\r
- DATA_ENSURE(0);\r
- code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
- if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;\r
+ mb_len = enclen(encode, s);\r
+ ss = s;\r
+ s += mb_len;\r
+ DATA_ENSURE(0);\r
+ code = ONIGENC_MBC_TO_CODE(encode, ss, s);\r
+ if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
+#endif\r
\r
- case OP_ANYCHAR: MOP_IN(OP_ANYCHAR);\r
+ case OP_ANYCHAR: SOP_IN(OP_ANYCHAR);\r
DATA_ENSURE(1);\r
n = enclen(encode, s);\r
DATA_ENSURE(n);\r
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
s += n;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_ANYCHAR_ML: MOP_IN(OP_ANYCHAR_ML);\r
+ case OP_ANYCHAR_ML: SOP_IN(OP_ANYCHAR_ML);\r
DATA_ENSURE(1);\r
n = enclen(encode, s);\r
DATA_ENSURE(n);\r
s += n;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_ANYCHAR_STAR: MOP_IN(OP_ANYCHAR_STAR);\r
+ case OP_ANYCHAR_STAR: SOP_IN(OP_ANYCHAR_STAR);\r
while (DATA_ENSURE_CHECK1) {\r
- STACK_PUSH_ALT(p, s, sprev);\r
- n = enclen(encode, s);\r
+ STACK_PUSH_ALT(p, s, sprev);\r
+ n = enclen(encode, s);\r
DATA_ENSURE(n);\r
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
sprev = s;\r
s += n;\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
+ continue;\r
break;\r
\r
- case OP_ANYCHAR_ML_STAR: MOP_IN(OP_ANYCHAR_ML_STAR);\r
+ case OP_ANYCHAR_ML_STAR: SOP_IN(OP_ANYCHAR_ML_STAR);\r
while (DATA_ENSURE_CHECK1) {\r
- STACK_PUSH_ALT(p, s, sprev);\r
- n = enclen(encode, s);\r
- if (n > 1) {\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- s += n;\r
- }\r
- else {\r
- sprev = s;\r
- s++;\r
- }\r
- }\r
- MOP_OUT;\r
- break;\r
-\r
- case OP_ANYCHAR_STAR_PEEK_NEXT: MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);\r
+ STACK_PUSH_ALT(p, s, sprev);\r
+ n = enclen(encode, s);\r
+ if (n > 1) {\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ s += n;\r
+ }\r
+ else {\r
+ sprev = s;\r
+ s++;\r
+ }\r
+ }\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+\r
+ case OP_ANYCHAR_STAR_PEEK_NEXT: SOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);\r
while (DATA_ENSURE_CHECK1) {\r
- if (*p == *s) {\r
- STACK_PUSH_ALT(p + 1, s, sprev);\r
- }\r
- n = enclen(encode, s);\r
+ if (*p == *s) {\r
+ STACK_PUSH_ALT(p + 1, s, sprev);\r
+ }\r
+ n = enclen(encode, s);\r
DATA_ENSURE(n);\r
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
sprev = s;\r
s += n;\r
}\r
p++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_ANYCHAR_ML_STAR_PEEK_NEXT:MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);\r
+ case OP_ANYCHAR_ML_STAR_PEEK_NEXT:SOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);\r
while (DATA_ENSURE_CHECK1) {\r
- if (*p == *s) {\r
- STACK_PUSH_ALT(p + 1, s, sprev);\r
- }\r
- n = enclen(encode, s);\r
- if (n > 1) {\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- s += n;\r
- }\r
- else {\r
- sprev = s;\r
- s++;\r
- }\r
+ if (*p == *s) {\r
+ STACK_PUSH_ALT(p + 1, s, sprev);\r
+ }\r
+ n = enclen(encode, s);\r
+ if (n > 1) {\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ s += n;\r
+ }\r
+ else {\r
+ sprev = s;\r
+ s++;\r
+ }\r
}\r
p++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- case OP_STATE_CHECK_ANYCHAR_STAR: MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);\r
- GET_STATE_CHECK_NUM_INC(mem, p);\r
- while (DATA_ENSURE_CHECK1) {\r
- STATE_CHECK_VAL(scv, mem);\r
- if (scv) goto fail;\r
+ case OP_WORD: SOP_IN(OP_WORD);\r
+ DATA_ENSURE(1);\r
+ if (! ONIGENC_IS_MBC_WORD(encode, s, end))\r
+ goto fail;\r
\r
- STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);\r
- n = enclen(encode, s);\r
- DATA_ENSURE(n);\r
- if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;\r
- sprev = s;\r
- s += n;\r
- }\r
- MOP_OUT;\r
+ s += enclen(encode, s);\r
+ SOP_OUT;\r
break;\r
\r
- case OP_STATE_CHECK_ANYCHAR_ML_STAR:\r
- MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);\r
-\r
- GET_STATE_CHECK_NUM_INC(mem, p);\r
- while (DATA_ENSURE_CHECK1) {\r
- STATE_CHECK_VAL(scv, mem);\r
- if (scv) goto fail;\r
-\r
- STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);\r
- n = enclen(encode, s);\r
- if (n > 1) {\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- s += n;\r
- }\r
- else {\r
- sprev = s;\r
- s++;\r
- }\r
- }\r
- MOP_OUT;\r
- break;\r
-#endif /* USE_COMBINATION_EXPLOSION_CHECK */\r
-\r
- case OP_WORD: MOP_IN(OP_WORD);\r
+ case OP_WORD_ASCII: SOP_IN(OP_WORD_ASCII);\r
DATA_ENSURE(1);\r
- if (! ONIGENC_IS_MBC_WORD(encode, s, end))\r
- goto fail;\r
+ if (! ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))\r
+ goto fail;\r
\r
s += enclen(encode, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_NOT_WORD: MOP_IN(OP_NOT_WORD);\r
+ case OP_NO_WORD: SOP_IN(OP_NO_WORD);\r
DATA_ENSURE(1);\r
if (ONIGENC_IS_MBC_WORD(encode, s, end))\r
- goto fail;\r
+ goto fail;\r
\r
s += enclen(encode, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
break;\r
\r
- case OP_WORD_BOUND: MOP_IN(OP_WORD_BOUND);\r
- if (ON_STR_BEGIN(s)) {\r
- DATA_ENSURE(1);\r
- if (! ONIGENC_IS_MBC_WORD(encode, s, end))\r
- goto fail;\r
- }\r
- else if (ON_STR_END(s)) {\r
- if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))\r
- goto fail;\r
- }\r
- else {\r
- if (ONIGENC_IS_MBC_WORD(encode, s, end)\r
- == ONIGENC_IS_MBC_WORD(encode, sprev, end))\r
- goto fail;\r
+ case OP_NO_WORD_ASCII: SOP_IN(OP_NO_WORD_ASCII);\r
+ DATA_ENSURE(1);\r
+ if (ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))\r
+ goto fail;\r
+\r
+ s += enclen(encode, s);\r
+ SOP_OUT;\r
+ break;\r
+\r
+ case OP_WORD_BOUNDARY: SOP_IN(OP_WORD_BOUNDARY);\r
+ {\r
+ ModeType mode;\r
+ GET_MODE_INC(mode, p); /* ascii_mode */\r
+\r
+ if (ON_STR_BEGIN(s)) {\r
+ DATA_ENSURE(1);\r
+ if (! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))\r
+ goto fail;\r
+ }\r
+ else if (ON_STR_END(s)) {\r
+ if (! IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
+ goto fail;\r
+ }\r
+ else {\r
+ if (IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)\r
+ == IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
+ goto fail;\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_NOT_WORD_BOUND: MOP_IN(OP_NOT_WORD_BOUND);\r
- if (ON_STR_BEGIN(s)) {\r
- if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))\r
- goto fail;\r
- }\r
- else if (ON_STR_END(s)) {\r
- if (ONIGENC_IS_MBC_WORD(encode, sprev, end))\r
- goto fail;\r
- }\r
- else {\r
- if (ONIGENC_IS_MBC_WORD(encode, s, end)\r
- != ONIGENC_IS_MBC_WORD(encode, sprev, end))\r
- goto fail;\r
+ case OP_NO_WORD_BOUNDARY: SOP_IN(OP_NO_WORD_BOUNDARY);\r
+ {\r
+ ModeType mode;\r
+ GET_MODE_INC(mode, p); /* ascii_mode */\r
+\r
+ if (ON_STR_BEGIN(s)) {\r
+ if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode))\r
+ goto fail;\r
+ }\r
+ else if (ON_STR_END(s)) {\r
+ if (IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
+ goto fail;\r
+ }\r
+ else {\r
+ if (IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)\r
+ != IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode))\r
+ goto fail;\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
#ifdef USE_WORD_BEGIN_END\r
- case OP_WORD_BEGIN: MOP_IN(OP_WORD_BEGIN);\r
- if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {\r
- if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {\r
- MOP_OUT;\r
- continue;\r
- }\r
+ case OP_WORD_BEGIN: SOP_IN(OP_WORD_BEGIN);\r
+ {\r
+ ModeType mode;\r
+ GET_MODE_INC(mode, p); /* ascii_mode */\r
+\r
+ if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {\r
+ if (ON_STR_BEGIN(s) || !IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
+ }\r
}\r
goto fail;\r
break;\r
\r
- case OP_WORD_END: MOP_IN(OP_WORD_END);\r
- if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {\r
- if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {\r
- MOP_OUT;\r
- continue;\r
- }\r
+ case OP_WORD_END: SOP_IN(OP_WORD_END);\r
+ {\r
+ ModeType mode;\r
+ GET_MODE_INC(mode, p); /* ascii_mode */\r
+\r
+ if (!ON_STR_BEGIN(s) && IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {\r
+ if (ON_STR_END(s) || ! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
+ }\r
}\r
goto fail;\r
break;\r
#endif\r
\r
- case OP_BEGIN_BUF: MOP_IN(OP_BEGIN_BUF);\r
+ case OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:\r
+ SOP_IN(OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);\r
+ if (onigenc_egcb_is_break_position(encode, s, sprev, str, end)) {\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
+ goto fail;\r
+ break;\r
+\r
+ case OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:\r
+ SOP_IN(OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);\r
+ if (onigenc_egcb_is_break_position(encode, s, sprev, str, end))\r
+ goto fail;\r
+\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+\r
+ case OP_BEGIN_BUF: SOP_IN(OP_BEGIN_BUF);\r
if (! ON_STR_BEGIN(s)) goto fail;\r
\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_END_BUF: MOP_IN(OP_END_BUF);\r
+ case OP_END_BUF: SOP_IN(OP_END_BUF);\r
if (! ON_STR_END(s)) goto fail;\r
\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_BEGIN_LINE: MOP_IN(OP_BEGIN_LINE);\r
+ case OP_BEGIN_LINE: SOP_IN(OP_BEGIN_LINE);\r
if (ON_STR_BEGIN(s)) {\r
- if (IS_NOTBOL(msa->options)) goto fail;\r
- MOP_OUT;\r
- continue;\r
+ if (IS_NOTBOL(msa->options)) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
}\r
else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
goto fail;\r
break;\r
\r
- case OP_END_LINE: MOP_IN(OP_END_LINE);\r
+ case OP_END_LINE: SOP_IN(OP_END_LINE);\r
if (ON_STR_END(s)) {\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
+ if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
#endif\r
- if (IS_NOTEOL(msa->options)) goto fail;\r
- MOP_OUT;\r
- continue;\r
+ if (IS_NOTEOL(msa->options)) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- }\r
+ }\r
#endif\r
}\r
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
#endif\r
goto fail;\r
break;\r
\r
- case OP_SEMI_END_BUF: MOP_IN(OP_SEMI_END_BUF);\r
+ case OP_SEMI_END_BUF: SOP_IN(OP_SEMI_END_BUF);\r
if (ON_STR_END(s)) {\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
+ if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {\r
#endif\r
- if (IS_NOTEOL(msa->options)) goto fail;\r
- MOP_OUT;\r
- continue;\r
+ if (IS_NOTEOL(msa->options)) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- }\r
+ }\r
#endif\r
}\r
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&\r
- ON_STR_END(s + enclen(encode, s))) {\r
- MOP_OUT;\r
- continue;\r
+ ON_STR_END(s + enclen(encode, s))) {\r
+ SOP_OUT;\r
+ continue;\r
}\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {\r
UChar* ss = s + enclen(encode, s);\r
- ss += enclen(encode, ss);\r
+ ss += enclen(encode, ss);\r
if (ON_STR_END(ss)) {\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
}\r
}\r
goto fail;\r
break;\r
\r
- case OP_BEGIN_POSITION: MOP_IN(OP_BEGIN_POSITION);\r
+ case OP_BEGIN_POSITION: SOP_IN(OP_BEGIN_POSITION);\r
if (s != msa->start)\r
- goto fail;\r
+ goto fail;\r
\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_MEMORY_START_PUSH: MOP_IN(OP_MEMORY_START_PUSH);\r
+ case OP_MEMORY_START_PUSH: SOP_IN(OP_MEMORY_START_PUSH);\r
GET_MEMNUM_INC(mem, p);\r
STACK_PUSH_MEM_START(mem, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_MEMORY_START: MOP_IN(OP_MEMORY_START);\r
+ case OP_MEMORY_START: SOP_IN(OP_MEMORY_START);\r
GET_MEMNUM_INC(mem, p);\r
- mem_start_stk[mem] = (OnigStackIndex )((void* )s);\r
- MOP_OUT;\r
+ mem_start_stk[mem] = (StackIndex )((void* )s);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_MEMORY_END_PUSH: MOP_IN(OP_MEMORY_END_PUSH);\r
+ case OP_MEMORY_END_PUSH: SOP_IN(OP_MEMORY_END_PUSH);\r
GET_MEMNUM_INC(mem, p);\r
STACK_PUSH_MEM_END(mem, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_MEMORY_END: MOP_IN(OP_MEMORY_END);\r
+ case OP_MEMORY_END: SOP_IN(OP_MEMORY_END);\r
GET_MEMNUM_INC(mem, p);\r
- mem_end_stk[mem] = (OnigStackIndex )((void* )s);\r
- MOP_OUT;\r
+ mem_end_stk[mem] = (StackIndex )((void* )s);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
-#ifdef USE_SUBEXP_CALL\r
- case OP_MEMORY_END_PUSH_REC: MOP_IN(OP_MEMORY_END_PUSH_REC);\r
+#ifdef USE_CALL\r
+ case OP_MEMORY_END_PUSH_REC: SOP_IN(OP_MEMORY_END_PUSH_REC);\r
GET_MEMNUM_INC(mem, p);\r
STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */\r
STACK_PUSH_MEM_END(mem, s);\r
mem_start_stk[mem] = GET_STACK_INDEX(stkp);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_MEMORY_END_REC: MOP_IN(OP_MEMORY_END_REC);\r
+ case OP_MEMORY_END_REC: SOP_IN(OP_MEMORY_END_REC);\r
GET_MEMNUM_INC(mem, p);\r
- mem_end_stk[mem] = (OnigStackIndex )((void* )s);\r
+ mem_end_stk[mem] = (StackIndex )((void* )s);\r
STACK_GET_MEM_START(mem, stkp);\r
\r
- if (BIT_STATUS_AT(reg->bt_mem_start, mem))\r
- mem_start_stk[mem] = GET_STACK_INDEX(stkp);\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
+ mem_start_stk[mem] = GET_STACK_INDEX(stkp);\r
else\r
- mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);\r
+ mem_start_stk[mem] = (StackIndex )((void* )stkp->u.mem.pstr);\r
\r
STACK_PUSH_MEM_END_MARK(mem);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
#endif\r
\r
- case OP_BACKREF1: MOP_IN(OP_BACKREF1);\r
+ case OP_BACKREF1: SOP_IN(OP_BACKREF1);\r
mem = 1;\r
goto backref;\r
break;\r
\r
- case OP_BACKREF2: MOP_IN(OP_BACKREF2);\r
+ case OP_BACKREF2: SOP_IN(OP_BACKREF2);\r
mem = 2;\r
goto backref;\r
break;\r
\r
- case OP_BACKREFN: MOP_IN(OP_BACKREFN);\r
+ case OP_BACKREF_N: SOP_IN(OP_BACKREF_N);\r
GET_MEMNUM_INC(mem, p);\r
backref:\r
{\r
- int len;\r
- UChar *pstart, *pend;\r
+ int len;\r
+ UChar *pstart, *pend;\r
\r
- /* if you want to remove following line, \r
- you should check in parse and compile time. */\r
- if (mem > num_mem) goto fail;\r
- if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
- if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
+ if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
+ if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
\r
- if (BIT_STATUS_AT(reg->bt_mem_start, mem))\r
- pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
- else\r
- pstart = (UChar* )((void* )mem_start_stk[mem]);\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
+ pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
+ else\r
+ pstart = (UChar* )((void* )mem_start_stk[mem]);\r
\r
- pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)\r
- ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[mem]));\r
- n = (int)(pend - pstart);\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- STRING_CMP(pstart, s, n);\r
- while (sprev + (len = enclen(encode, sprev)) < s)\r
- sprev += len;\r
+ pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
+ ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[mem]));\r
+ n = (int )(pend - pstart);\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ STRING_CMP(pstart, s, n);\r
+ while (sprev + (len = enclen(encode, sprev)) < s)\r
+ sprev += len;\r
\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
break;\r
\r
- case OP_BACKREFN_IC: MOP_IN(OP_BACKREFN_IC);\r
+ case OP_BACKREF_N_IC: SOP_IN(OP_BACKREF_N_IC);\r
GET_MEMNUM_INC(mem, p);\r
{\r
- int len;\r
- UChar *pstart, *pend;\r
+ int len;\r
+ UChar *pstart, *pend;\r
\r
- /* if you want to remove following line, \r
- you should check in parse and compile time. */\r
- if (mem > num_mem) goto fail;\r
- if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
- if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
+ if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
+ if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;\r
\r
- if (BIT_STATUS_AT(reg->bt_mem_start, mem))\r
- pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
- else\r
- pstart = (UChar* )((void* )mem_start_stk[mem]);\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
+ pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
+ else\r
+ pstart = (UChar* )((void* )mem_start_stk[mem]);\r
\r
- pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)\r
- ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[mem]));\r
- n = (int)(pend - pstart);\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- STRING_CMP_IC(case_fold_flag, pstart, &s, n);\r
- while (sprev + (len = enclen(encode, sprev)) < s)\r
- sprev += len;\r
+ pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
+ ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[mem]));\r
+ n = (int )(pend - pstart);\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ STRING_CMP_IC(case_fold_flag, pstart, &s, n);\r
+ while (sprev + (len = enclen(encode, sprev)) < s)\r
+ sprev += len;\r
\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
break;\r
\r
- case OP_BACKREF_MULTI: MOP_IN(OP_BACKREF_MULTI);\r
+ case OP_BACKREF_MULTI: SOP_IN(OP_BACKREF_MULTI);\r
{\r
- int len, is_fail;\r
- UChar *pstart, *pend, *swork;\r
-\r
- GET_LENGTH_INC(tlen, p);\r
- for (i = 0; i < tlen; i++) {\r
- GET_MEMNUM_INC(mem, p);\r
-\r
- if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
- if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
-\r
- if (BIT_STATUS_AT(reg->bt_mem_start, mem))\r
- pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
- else\r
- pstart = (UChar* )((void* )mem_start_stk[mem]);\r
-\r
- pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)\r
- ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[mem]));\r
- n = (int)(pend - pstart);\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- swork = s;\r
- STRING_CMP_VALUE(pstart, swork, n, is_fail);\r
- if (is_fail) continue;\r
- s = swork;\r
- while (sprev + (len = enclen(encode, sprev)) < s)\r
- sprev += len;\r
-\r
- p += (SIZE_MEMNUM * (tlen - i - 1));\r
- break; /* success */\r
- }\r
- if (i == tlen) goto fail;\r
- MOP_OUT;\r
- continue;\r
- }\r
- break;\r
-\r
- case OP_BACKREF_MULTI_IC: MOP_IN(OP_BACKREF_MULTI_IC);\r
+ int len, is_fail;\r
+ UChar *pstart, *pend, *swork;\r
+\r
+ GET_LENGTH_INC(tlen, p);\r
+ for (i = 0; i < tlen; i++) {\r
+ GET_MEMNUM_INC(mem, p);\r
+\r
+ if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
+ if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
+\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
+ pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
+ else\r
+ pstart = (UChar* )((void* )mem_start_stk[mem]);\r
+\r
+ pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
+ ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[mem]));\r
+ n = (int )(pend - pstart);\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ swork = s;\r
+ STRING_CMP_VALUE(pstart, swork, n, is_fail);\r
+ if (is_fail) continue;\r
+ s = swork;\r
+ while (sprev + (len = enclen(encode, sprev)) < s)\r
+ sprev += len;\r
+\r
+ p += (SIZE_MEMNUM * (tlen - i - 1));\r
+ break; /* success */\r
+ }\r
+ if (i == tlen) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
+ break;\r
+\r
+ case OP_BACKREF_MULTI_IC: SOP_IN(OP_BACKREF_MULTI_IC);\r
{\r
- int len, is_fail;\r
- UChar *pstart, *pend, *swork;\r
-\r
- GET_LENGTH_INC(tlen, p);\r
- for (i = 0; i < tlen; i++) {\r
- GET_MEMNUM_INC(mem, p);\r
-\r
- if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
- if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
-\r
- if (BIT_STATUS_AT(reg->bt_mem_start, mem))\r
- pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
- else\r
- pstart = (UChar* )((void* )mem_start_stk[mem]);\r
-\r
- pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)\r
- ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
- : (UChar* )((void* )mem_end_stk[mem]));\r
- n = (int)(pend - pstart);\r
- DATA_ENSURE(n);\r
- sprev = s;\r
- swork = s;\r
- STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, is_fail);\r
- if (is_fail) continue;\r
- s = swork;\r
- while (sprev + (len = enclen(encode, sprev)) < s)\r
- sprev += len;\r
-\r
- p += (SIZE_MEMNUM * (tlen - i - 1));\r
- break; /* success */\r
- }\r
- if (i == tlen) goto fail;\r
- MOP_OUT;\r
- continue;\r
+ int len, is_fail;\r
+ UChar *pstart, *pend, *swork;\r
+\r
+ GET_LENGTH_INC(tlen, p);\r
+ for (i = 0; i < tlen; i++) {\r
+ GET_MEMNUM_INC(mem, p);\r
+\r
+ if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
+ if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
+\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, mem))\r
+ pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;\r
+ else\r
+ pstart = (UChar* )((void* )mem_start_stk[mem]);\r
+\r
+ pend = (MEM_STATUS_AT(reg->bt_mem_end, mem)\r
+ ? STACK_AT(mem_end_stk[mem])->u.mem.pstr\r
+ : (UChar* )((void* )mem_end_stk[mem]));\r
+ n = (int )(pend - pstart);\r
+ DATA_ENSURE(n);\r
+ sprev = s;\r
+ swork = s;\r
+ STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, is_fail);\r
+ if (is_fail) continue;\r
+ s = swork;\r
+ while (sprev + (len = enclen(encode, sprev)) < s)\r
+ sprev += len;\r
+\r
+ p += (SIZE_MEMNUM * (tlen - i - 1));\r
+ break; /* success */\r
+ }\r
+ if (i == tlen) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
}\r
break;\r
\r
#ifdef USE_BACKREF_WITH_LEVEL\r
case OP_BACKREF_WITH_LEVEL:\r
{\r
- int len;\r
- OnigOptionType ic;\r
- LengthType level;\r
+ int len;\r
+ OnigOptionType ic;\r
+ LengthType level;\r
\r
- GET_OPTION_INC(ic, p);\r
- GET_LENGTH_INC(level, p);\r
- GET_LENGTH_INC(tlen, p);\r
+ GET_OPTION_INC(ic, p);\r
+ GET_LENGTH_INC(level, p);\r
+ GET_LENGTH_INC(tlen, p);\r
\r
- sprev = s;\r
- if (backref_match_at_nested_level(reg, stk, stk_base, ic\r
- , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {\r
- while (sprev + (len = enclen(encode, sprev)) < s)\r
- sprev += len;\r
-\r
- p += (SIZE_MEMNUM * tlen);\r
- }\r
- else\r
- goto fail;\r
+ sprev = s;\r
+ if (backref_match_at_nested_level(reg, stk, stk_base, ic\r
+ , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {\r
+ if (sprev < end) {\r
+ while (sprev + (len = enclen(encode, sprev)) < s)\r
+ sprev += len;\r
+ }\r
+ p += (SIZE_MEMNUM * tlen);\r
+ }\r
+ else\r
+ goto fail;\r
\r
- MOP_OUT;\r
- continue;\r
+ SOP_OUT;\r
+ continue;\r
}\r
- \r
break;\r
#endif\r
\r
-#if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */\r
- case OP_SET_OPTION_PUSH: MOP_IN(OP_SET_OPTION_PUSH);\r
- GET_OPTION_INC(option, p);\r
- STACK_PUSH_ALT(p, s, sprev);\r
- p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;\r
- MOP_OUT;\r
- continue;\r
+ case OP_BACKREF_CHECK: SOP_IN(OP_BACKREF_CHECK);\r
+ {\r
+ GET_LENGTH_INC(tlen, p);\r
+ for (i = 0; i < tlen; i++) {\r
+ GET_MEMNUM_INC(mem, p);\r
+\r
+ if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;\r
+ if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;\r
+\r
+ p += (SIZE_MEMNUM * (tlen - i - 1));\r
+ break; /* success */\r
+ }\r
+ if (i == tlen) goto fail;\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
break;\r
\r
- case OP_SET_OPTION: MOP_IN(OP_SET_OPTION);\r
- GET_OPTION_INC(option, p);\r
- MOP_OUT;\r
- continue;\r
+#ifdef USE_BACKREF_WITH_LEVEL\r
+ case OP_BACKREF_CHECK_WITH_LEVEL:\r
+ {\r
+ LengthType level;\r
+\r
+ GET_LENGTH_INC(level, p);\r
+ GET_LENGTH_INC(tlen, p);\r
+\r
+ if (backref_check_at_nested_level(reg, stk, stk_base,\r
+ (int )level, (int )tlen, p) != 0) {\r
+ p += (SIZE_MEMNUM * tlen);\r
+ }\r
+ else\r
+ goto fail;\r
+\r
+ SOP_OUT;\r
+ continue;\r
+ }\r
break;\r
#endif\r
\r
- case OP_NULL_CHECK_START: MOP_IN(OP_NULL_CHECK_START);\r
+ case OP_EMPTY_CHECK_START: SOP_IN(OP_EMPTY_CHECK_START);\r
GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
- STACK_PUSH_NULL_CHECK_START(mem, s);\r
- MOP_OUT;\r
+ STACK_PUSH_EMPTY_CHECK_START(mem, s);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_NULL_CHECK_END: MOP_IN(OP_NULL_CHECK_END);\r
+ case OP_EMPTY_CHECK_END: SOP_IN(OP_EMPTY_CHECK_END);\r
{\r
- int isnull;\r
+ int is_empty;\r
\r
- GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
- STACK_NULL_CHECK(isnull, mem, s);\r
- if (isnull) {\r
+ GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
+ STACK_EMPTY_CHECK(is_empty, mem, s);\r
+ if (is_empty) {\r
#ifdef ONIG_DEBUG_MATCH\r
- fprintf(stderr, "NULL_CHECK_END: skip id:%d, s:%d\n",\r
- (int )mem, (int )s);\r
-#endif\r
- null_check_found:\r
- /* empty loop founded, skip next instruction */\r
- switch (*p++) {\r
- case OP_JUMP:\r
- case OP_PUSH:\r
- p += SIZE_RELADDR;\r
- break;\r
- case OP_REPEAT_INC:\r
- case OP_REPEAT_INC_NG:\r
- case OP_REPEAT_INC_SG:\r
- case OP_REPEAT_INC_NG_SG:\r
- p += SIZE_MEMNUM;\r
- break;\r
- default:\r
- goto unexpected_bytecode_error;\r
- break;\r
- }\r
- }\r
- }\r
- MOP_OUT;\r
+ fprintf(stderr, "EMPTY_CHECK_END: skip id:%d, s:%p\n", (int )mem, s);\r
+#endif\r
+ empty_check_found:\r
+ /* empty loop founded, skip next instruction */\r
+ switch (*p++) {\r
+ case OP_JUMP:\r
+ case OP_PUSH:\r
+ p += SIZE_RELADDR;\r
+ break;\r
+ case OP_REPEAT_INC:\r
+ case OP_REPEAT_INC_NG:\r
+ case OP_REPEAT_INC_SG:\r
+ case OP_REPEAT_INC_NG_SG:\r
+ p += SIZE_MEMNUM;\r
+ break;\r
+ default:\r
+ goto unexpected_bytecode_error;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
-#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT\r
- case OP_NULL_CHECK_END_MEMST: MOP_IN(OP_NULL_CHECK_END_MEMST);\r
+#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
+ case OP_EMPTY_CHECK_END_MEMST: SOP_IN(OP_EMPTY_CHECK_END_MEMST);\r
{\r
- int isnull;\r
+ int is_empty;\r
\r
- GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
- STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);\r
- if (isnull) {\r
+ GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
+ STACK_EMPTY_CHECK_MEM(is_empty, mem, s, reg);\r
+ if (is_empty) {\r
#ifdef ONIG_DEBUG_MATCH\r
- fprintf(stderr, "NULL_CHECK_END_MEMST: skip id:%d, s:%d\n",\r
- (int )mem, (int )s);\r
+ fprintf(stderr, "EMPTY_CHECK_END_MEM: skip id:%d, s:%p\n", (int)mem, s);\r
#endif\r
- if (isnull == -1) goto fail;\r
- goto null_check_found;\r
- }\r
+ if (is_empty == -1) goto fail;\r
+ goto empty_check_found;\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
#endif\r
\r
-#ifdef USE_SUBEXP_CALL\r
- case OP_NULL_CHECK_END_MEMST_PUSH:\r
- MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);\r
+#ifdef USE_CALL\r
+ case OP_EMPTY_CHECK_END_MEMST_PUSH:\r
+ SOP_IN(OP_EMPTY_CHECK_END_MEMST_PUSH);\r
{\r
- int isnull;\r
+ int is_empty;\r
\r
- GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
-#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT\r
- STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);\r
+ GET_MEMNUM_INC(mem, p); /* mem: null check id */\r
+#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT\r
+ STACK_EMPTY_CHECK_MEM_REC(is_empty, mem, s, reg);\r
#else\r
- STACK_NULL_CHECK_REC(isnull, mem, s);\r
+ STACK_EMPTY_CHECK_REC(is_empty, mem, s);\r
#endif\r
- if (isnull) {\r
+ if (is_empty) {\r
#ifdef ONIG_DEBUG_MATCH\r
- fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip id:%d, s:%d\n",\r
- (int )mem, (int )s);\r
+ fprintf(stderr, "EMPTY_CHECK_END_MEM_PUSH: skip id:%d, s:%p\n",\r
+ (int )mem, s);\r
#endif\r
- if (isnull == -1) goto fail;\r
- goto null_check_found;\r
- }\r
- else {\r
- STACK_PUSH_NULL_CHECK_END(mem);\r
- }\r
+ if (is_empty == -1) goto fail;\r
+ goto empty_check_found;\r
+ }\r
+ else {\r
+ STACK_PUSH_EMPTY_CHECK_END(mem);\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
#endif\r
\r
- case OP_JUMP: MOP_IN(OP_JUMP);\r
+ case OP_JUMP: SOP_IN(OP_JUMP);\r
GET_RELADDR_INC(addr, p);\r
p += addr;\r
- MOP_OUT;\r
- CHECK_INTERRUPT_IN_MATCH_AT;\r
+ SOP_OUT;\r
+ CHECK_INTERRUPT_IN_MATCH;\r
continue;\r
break;\r
\r
- case OP_PUSH: MOP_IN(OP_PUSH);\r
+ case OP_PUSH: SOP_IN(OP_PUSH);\r
GET_RELADDR_INC(addr, p);\r
STACK_PUSH_ALT(p + addr, s, sprev);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- case OP_STATE_CHECK_PUSH: MOP_IN(OP_STATE_CHECK_PUSH);\r
- GET_STATE_CHECK_NUM_INC(mem, p);\r
- STATE_CHECK_VAL(scv, mem);\r
- if (scv) goto fail;\r
-\r
+ case OP_PUSH_SUPER: SOP_IN(OP_PUSH_SUPER);\r
GET_RELADDR_INC(addr, p);\r
- STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);\r
- MOP_OUT;\r
+ STACK_PUSH_SUPER_ALT(p + addr, s, sprev);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_STATE_CHECK_PUSH_OR_JUMP: MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);\r
- GET_STATE_CHECK_NUM_INC(mem, p);\r
- GET_RELADDR_INC(addr, p);\r
- STATE_CHECK_VAL(scv, mem);\r
- if (scv) {\r
- p += addr;\r
- }\r
- else {\r
- STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);\r
- }\r
- MOP_OUT;\r
- continue;\r
- break;\r
-\r
- case OP_STATE_CHECK: MOP_IN(OP_STATE_CHECK);\r
- GET_STATE_CHECK_NUM_INC(mem, p);\r
- STATE_CHECK_VAL(scv, mem);\r
- if (scv) goto fail;\r
-\r
- STACK_PUSH_STATE_CHECK(s, mem);\r
- MOP_OUT;\r
- continue;\r
- break;\r
-#endif /* USE_COMBINATION_EXPLOSION_CHECK */\r
-\r
- case OP_POP: MOP_IN(OP_POP);\r
+ case OP_POP_OUT: SOP_IN(OP_POP_OUT);\r
STACK_POP_ONE;\r
- MOP_OUT;\r
+ /* for stop backtrack */\r
+ /* CHECK_RETRY_LIMIT_IN_MATCH; */\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_PUSH_OR_JUMP_EXACT1: MOP_IN(OP_PUSH_OR_JUMP_EXACT1);\r
+ case OP_PUSH_OR_JUMP_EXACT1: SOP_IN(OP_PUSH_OR_JUMP_EXACT1);\r
GET_RELADDR_INC(addr, p);\r
if (*p == *s && DATA_ENSURE_CHECK1) {\r
- p++;\r
- STACK_PUSH_ALT(p + addr, s, sprev);\r
- MOP_OUT;\r
- continue;\r
+ p++;\r
+ STACK_PUSH_ALT(p + addr, s, sprev);\r
+ SOP_OUT;\r
+ continue;\r
}\r
p += (addr + 1);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_PUSH_IF_PEEK_NEXT: MOP_IN(OP_PUSH_IF_PEEK_NEXT);\r
+ case OP_PUSH_IF_PEEK_NEXT: SOP_IN(OP_PUSH_IF_PEEK_NEXT);\r
GET_RELADDR_INC(addr, p);\r
if (*p == *s) {\r
- p++;\r
- STACK_PUSH_ALT(p + addr, s, sprev);\r
- MOP_OUT;\r
- continue;\r
+ p++;\r
+ STACK_PUSH_ALT(p + addr, s, sprev);\r
+ SOP_OUT;\r
+ continue;\r
}\r
p++;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_REPEAT: MOP_IN(OP_REPEAT);\r
+ case OP_REPEAT: SOP_IN(OP_REPEAT);\r
{\r
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
- GET_RELADDR_INC(addr, p);\r
+ GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
+ GET_RELADDR_INC(addr, p);\r
\r
- STACK_ENSURE(1);\r
- repeat_stk[mem] = GET_STACK_INDEX(stk);\r
- STACK_PUSH_REPEAT(mem, p);\r
+ STACK_ENSURE(1);\r
+ repeat_stk[mem] = GET_STACK_INDEX(stk);\r
+ STACK_PUSH_REPEAT(mem, p);\r
\r
- if (reg->repeat_range[mem].lower == 0) {\r
- STACK_PUSH_ALT(p + addr, s, sprev);\r
- }\r
+ if (reg->repeat_range[mem].lower == 0) {\r
+ STACK_PUSH_ALT(p + addr, s, sprev);\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_REPEAT_NG: MOP_IN(OP_REPEAT_NG);\r
+ case OP_REPEAT_NG: SOP_IN(OP_REPEAT_NG);\r
{\r
- GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
- GET_RELADDR_INC(addr, p);\r
+ GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
+ GET_RELADDR_INC(addr, p);\r
\r
- STACK_ENSURE(1);\r
- repeat_stk[mem] = GET_STACK_INDEX(stk);\r
- STACK_PUSH_REPEAT(mem, p);\r
+ STACK_ENSURE(1);\r
+ repeat_stk[mem] = GET_STACK_INDEX(stk);\r
+ STACK_PUSH_REPEAT(mem, p);\r
\r
- if (reg->repeat_range[mem].lower == 0) {\r
- STACK_PUSH_ALT(p, s, sprev);\r
- p += addr;\r
- }\r
+ if (reg->repeat_range[mem].lower == 0) {\r
+ STACK_PUSH_ALT(p, s, sprev);\r
+ p += addr;\r
+ }\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_REPEAT_INC: MOP_IN(OP_REPEAT_INC);\r
+ case OP_REPEAT_INC: SOP_IN(OP_REPEAT_INC);\r
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
si = repeat_stk[mem];\r
stkp = STACK_AT(si);\r
p = stkp->u.repeat.pcode;\r
}\r
STACK_PUSH_REPEAT_INC(si);\r
- MOP_OUT;\r
- CHECK_INTERRUPT_IN_MATCH_AT;\r
+ SOP_OUT;\r
+ CHECK_INTERRUPT_IN_MATCH;\r
continue;\r
break;\r
\r
- case OP_REPEAT_INC_SG: MOP_IN(OP_REPEAT_INC_SG);\r
+ case OP_REPEAT_INC_SG: SOP_IN(OP_REPEAT_INC_SG);\r
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
STACK_GET_REPEAT(mem, stkp);\r
si = GET_STACK_INDEX(stkp);\r
goto repeat_inc;\r
break;\r
\r
- case OP_REPEAT_INC_NG: MOP_IN(OP_REPEAT_INC_NG);\r
+ case OP_REPEAT_INC_NG: SOP_IN(OP_REPEAT_INC_NG);\r
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
si = repeat_stk[mem];\r
stkp = STACK_AT(si);\r
else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {\r
STACK_PUSH_REPEAT_INC(si);\r
}\r
- MOP_OUT;\r
- CHECK_INTERRUPT_IN_MATCH_AT;\r
+ SOP_OUT;\r
+ CHECK_INTERRUPT_IN_MATCH;\r
continue;\r
break;\r
\r
- case OP_REPEAT_INC_NG_SG: MOP_IN(OP_REPEAT_INC_NG_SG);\r
+ case OP_REPEAT_INC_NG_SG: SOP_IN(OP_REPEAT_INC_NG_SG);\r
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */\r
STACK_GET_REPEAT(mem, stkp);\r
si = GET_STACK_INDEX(stkp);\r
goto repeat_inc_ng;\r
break;\r
\r
- case OP_PUSH_POS: MOP_IN(OP_PUSH_POS);\r
+ case OP_PREC_READ_START: SOP_IN(OP_PREC_READ_START);\r
STACK_PUSH_POS(s, sprev);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_POP_POS: MOP_IN(OP_POP_POS);\r
+ case OP_PREC_READ_END: SOP_IN(OP_PREC_READ_END);\r
{\r
- STACK_POS_END(stkp);\r
- s = stkp->u.state.pstr;\r
- sprev = stkp->u.state.pstr_prev;\r
+ STACK_EXEC_TO_VOID(stkp);\r
+ s = stkp->u.state.pstr;\r
+ sprev = stkp->u.state.pstr_prev;\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_PUSH_POS_NOT: MOP_IN(OP_PUSH_POS_NOT);\r
+ case OP_PREC_READ_NOT_START: SOP_IN(OP_PREC_READ_NOT_START);\r
GET_RELADDR_INC(addr, p);\r
- STACK_PUSH_POS_NOT(p + addr, s, sprev);\r
- MOP_OUT;\r
+ STACK_PUSH_ALT_PREC_READ_NOT(p + addr, s, sprev);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_FAIL_POS: MOP_IN(OP_FAIL_POS);\r
- STACK_POP_TIL_POS_NOT;\r
+ case OP_PREC_READ_NOT_END: SOP_IN(OP_PREC_READ_NOT_END);\r
+ STACK_POP_TIL_ALT_PREC_READ_NOT;\r
goto fail;\r
break;\r
\r
- case OP_PUSH_STOP_BT: MOP_IN(OP_PUSH_STOP_BT);\r
- STACK_PUSH_STOP_BT;\r
- MOP_OUT;\r
+ case OP_ATOMIC_START: SOP_IN(OP_ATOMIC_START);\r
+ STACK_PUSH_TO_VOID_START;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_POP_STOP_BT: MOP_IN(OP_POP_STOP_BT);\r
- STACK_STOP_BT_END;\r
- MOP_OUT;\r
+ case OP_ATOMIC_END: SOP_IN(OP_ATOMIC_END);\r
+ STACK_EXEC_TO_VOID(stkp);\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_LOOK_BEHIND: MOP_IN(OP_LOOK_BEHIND);\r
+ case OP_LOOK_BEHIND: SOP_IN(OP_LOOK_BEHIND);\r
GET_LENGTH_INC(tlen, p);\r
s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);\r
if (IS_NULL(s)) goto fail;\r
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_PUSH_LOOK_BEHIND_NOT: MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);\r
+ case OP_LOOK_BEHIND_NOT_START: SOP_IN(OP_LOOK_BEHIND_NOT_START);\r
GET_RELADDR_INC(addr, p);\r
GET_LENGTH_INC(tlen, p);\r
q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);\r
if (IS_NULL(q)) {\r
- /* too short case -> success. ex. /(?<!XXX)a/.match("a")\r
- If you want to change to fail, replace following line. */\r
- p += addr;\r
- /* goto fail; */\r
+ /* too short case -> success. ex. /(?<!XXX)a/.match("a")\r
+ If you want to change to fail, replace following line. */\r
+ p += addr;\r
+ /* goto fail; */\r
}\r
else {\r
- STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev);\r
- s = q;\r
- sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);\r
+ STACK_PUSH_ALT_LOOK_BEHIND_NOT(p + addr, s, sprev);\r
+ s = q;\r
+ sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);\r
}\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_FAIL_LOOK_BEHIND_NOT: MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);\r
- STACK_POP_TIL_LOOK_BEHIND_NOT;\r
+ case OP_LOOK_BEHIND_NOT_END: SOP_IN(OP_LOOK_BEHIND_NOT_END);\r
+ STACK_POP_TIL_ALT_LOOK_BEHIND_NOT;\r
goto fail;\r
break;\r
\r
-#ifdef USE_SUBEXP_CALL\r
- case OP_CALL: MOP_IN(OP_CALL);\r
+#ifdef USE_CALL\r
+ case OP_CALL: SOP_IN(OP_CALL);\r
GET_ABSADDR_INC(addr, p);\r
STACK_PUSH_CALL_FRAME(p);\r
p = reg->p + addr;\r
- MOP_OUT;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
- case OP_RETURN: MOP_IN(OP_RETURN);\r
+ case OP_RETURN: SOP_IN(OP_RETURN);\r
STACK_RETURN(p);\r
STACK_PUSH_RETURN;\r
- MOP_OUT;\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+#endif\r
+\r
+ case OP_PUSH_SAVE_VAL: SOP_IN(OP_PUSH_SAVE_VAL);\r
+ {\r
+ SaveType type;\r
+ GET_SAVE_TYPE_INC(type, p);\r
+ GET_MEMNUM_INC(mem, p); /* mem: save id */\r
+ switch ((enum SaveType )type) {\r
+ case SAVE_KEEP:\r
+ STACK_PUSH_SAVE_VAL(mem, type, s);\r
+ break;\r
+\r
+ case SAVE_S:\r
+ STACK_PUSH_SAVE_VAL_WITH_SPREV(mem, type, s);\r
+ break;\r
+\r
+ case SAVE_RIGHT_RANGE:\r
+ STACK_PUSH_SAVE_VAL(mem, SAVE_RIGHT_RANGE, right_range);\r
+ break;\r
+ }\r
+ }\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+\r
+ case OP_UPDATE_VAR: SOP_IN(OP_UPDATE_VAR);\r
+ {\r
+ UpdateVarType type;\r
+ enum SaveType save_type;\r
+\r
+ GET_UPDATE_VAR_TYPE_INC(type, p);\r
+ GET_MEMNUM_INC(mem, p); /* mem: save id */\r
+ switch ((enum UpdateVarType )type) {\r
+ case UPDATE_VAR_KEEP_FROM_STACK_LAST:\r
+ STACK_GET_SAVE_VAL_TYPE_LAST(SAVE_KEEP, keep);\r
+ break;\r
+ case UPDATE_VAR_S_FROM_STACK:\r
+ STACK_GET_SAVE_VAL_TYPE_LAST_ID_WITH_SPREV(SAVE_S, mem, s);\r
+ break;\r
+ case UPDATE_VAR_RIGHT_RANGE_FROM_S_STACK:\r
+ save_type = SAVE_S;\r
+ goto get_save_val_type_last_id;\r
+ break;\r
+ case UPDATE_VAR_RIGHT_RANGE_FROM_STACK:\r
+ save_type = SAVE_RIGHT_RANGE;\r
+ get_save_val_type_last_id:\r
+ STACK_GET_SAVE_VAL_TYPE_LAST_ID(save_type, mem, right_range);\r
+ break;\r
+ case UPDATE_VAR_RIGHT_RANGE_INIT:\r
+ INIT_RIGHT_RANGE;\r
+ break;\r
+ }\r
+ }\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+\r
+#ifdef USE_CALLOUT\r
+ case OP_CALLOUT_CONTENTS: SOP_IN(OP_CALLOUT_CONTENTS);\r
+ of = ONIG_CALLOUT_OF_CONTENTS;\r
+ goto callout_common_entry;\r
+\r
+ SOP_OUT;\r
+ continue;\r
+ break;\r
+\r
+ case OP_CALLOUT_NAME: SOP_IN(OP_CALLOUT_NAME);\r
+ {\r
+ int call_result;\r
+ int name_id;\r
+ int num;\r
+ int in;\r
+ CalloutListEntry* e;\r
+ OnigCalloutFunc func;\r
+ OnigCalloutArgs args;\r
+\r
+ of = ONIG_CALLOUT_OF_NAME;\r
+ GET_MEMNUM_INC(name_id, p);\r
+\r
+ callout_common_entry:\r
+ GET_MEMNUM_INC(num, p);\r
+ e = onig_reg_callout_list_at(reg, num);\r
+ in = e->in;\r
+ if (of == ONIG_CALLOUT_OF_NAME) {\r
+ func = onig_get_callout_start_func(reg, num);\r
+ }\r
+ else {\r
+ name_id = ONIG_NON_NAME_ID;\r
+ func = msa->mp->progress_callout_of_contents;\r
+ }\r
+\r
+ if (IS_NOT_NULL(func) && (in & ONIG_CALLOUT_IN_PROGRESS) != 0) {\r
+ CALLOUT_BODY(func, ONIG_CALLOUT_IN_PROGRESS, name_id,\r
+ num, msa->mp->callout_user_data, args, call_result);\r
+ switch (call_result) {\r
+ case ONIG_CALLOUT_FAIL:\r
+ goto fail;\r
+ break;\r
+ case ONIG_CALLOUT_SUCCESS:\r
+ goto retraction_callout2;\r
+ break;\r
+ default: /* error code */\r
+ if (call_result > 0) {\r
+ call_result = ONIGERR_INVALID_ARGUMENT;\r
+ }\r
+ best_len = call_result;\r
+ goto finish;\r
+ break;\r
+ }\r
+ }\r
+ else {\r
+ retraction_callout2:\r
+ if ((in & ONIG_CALLOUT_IN_RETRACTION) != 0) {\r
+ if (of == ONIG_CALLOUT_OF_NAME) {\r
+ if (IS_NOT_NULL(func)) {\r
+ STACK_PUSH_CALLOUT_NAME(name_id, num, func);\r
+ }\r
+ }\r
+ else {\r
+ func = msa->mp->retraction_callout_of_contents;\r
+ if (IS_NOT_NULL(func)) {\r
+ STACK_PUSH_CALLOUT_CONTENTS(num, func);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ SOP_OUT;\r
continue;\r
break;\r
#endif\r
break;\r
\r
fail:\r
- MOP_OUT;\r
+ SOP_OUT;\r
/* fall */\r
- case OP_FAIL: MOP_IN(OP_FAIL);\r
+ case OP_FAIL: SOP_IN(OP_FAIL);\r
STACK_POP;\r
p = stk->u.state.pcode;\r
s = stk->u.state.pstr;\r
sprev = stk->u.state.pstr_prev;\r
-\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- if (stk->u.state.state_check != 0) {\r
- stk->type = STK_STATE_CHECK_MARK;\r
- stk++;\r
- }\r
-#endif\r
-\r
- MOP_OUT;\r
+ CHECK_RETRY_LIMIT_IN_MATCH;\r
+ SOP_OUT;\r
continue;\r
break;\r
\r
\r
finish:\r
STACK_SAVE;\r
- xfree(alloca_base);\r
return best_len;\r
\r
#ifdef ONIG_DEBUG\r
stack_error:\r
STACK_SAVE;\r
- xfree(alloca_base);\r
return ONIGERR_STACK_BUG;\r
#endif\r
\r
bytecode_error:\r
STACK_SAVE;\r
- xfree(alloca_base);\r
return ONIGERR_UNDEFINED_BYTECODE;\r
\r
unexpected_bytecode_error:\r
STACK_SAVE;\r
- xfree(alloca_base);\r
return ONIGERR_UNEXPECTED_BYTECODE;\r
+\r
+#ifdef USE_RETRY_LIMIT_IN_MATCH\r
+ retry_limit_in_match_over:\r
+ STACK_SAVE;\r
+ return ONIGERR_RETRY_LIMIT_IN_MATCH_OVER;\r
+#endif\r
}\r
\r
\r
static UChar*\r
slow_search(OnigEncoding enc, UChar* target, UChar* target_end,\r
- const UChar* text, const UChar* text_end, UChar* text_range)\r
+ const UChar* text, const UChar* text_end, UChar* text_range)\r
{\r
UChar *t, *p, *s, *end;\r
\r
p = s + 1;\r
t = target + 1;\r
while (t < target_end) {\r
- if (*t != *p++)\r
- break;\r
- t++;\r
+ if (*t != *p++)\r
+ break;\r
+ t++;\r
}\r
if (t == target_end)\r
- return s;\r
+ return s;\r
}\r
s += enclen(enc, s);\r
}\r
static int\r
str_lower_case_match(OnigEncoding enc, int case_fold_flag,\r
const UChar* t, const UChar* tend,\r
- const UChar* p, const UChar* end)\r
+ const UChar* p, const UChar* end)\r
{\r
int lowlen;\r
UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];\r
lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);\r
q = lowbuf;\r
while (lowlen > 0) {\r
- if (*t++ != *q++) return 0;\r
+ if (*t++ != *q++) return 0;\r
lowlen--;\r
}\r
}\r
\r
static UChar*\r
slow_search_ic(OnigEncoding enc, int case_fold_flag,\r
- UChar* target, UChar* target_end,\r
- const UChar* text, const UChar* text_end, UChar* text_range)\r
+ UChar* target, UChar* target_end,\r
+ const UChar* text, const UChar* text_end, UChar* text_range)\r
{\r
UChar *s, *end;\r
\r
\r
while (s < end) {\r
if (str_lower_case_match(enc, case_fold_flag, target, target_end,\r
- s, text_end))\r
+ s, text_end))\r
return s;\r
\r
s += enclen(enc, s);\r
\r
static UChar*\r
slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,\r
- const UChar* text, const UChar* adjust_text,\r
- const UChar* text_end, const UChar* text_start)\r
+ const UChar* text, const UChar* adjust_text,\r
+ const UChar* text_end, const UChar* text_start)\r
{\r
UChar *t, *p, *s;\r
\r
s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);\r
\r
while (s >= text) {\r
+ //if text is not null,the logic is correct.\r
+ //this function is only invoked by backward_search_range,parameter text come\r
+ //from range, which is checked by "if (range == 0) goto fail" in line 4512\r
+ //so the check is just for passing static analysis.\r
+ if(IS_NULL(s))break;\r
if (*s == *target) {\r
p = s + 1;\r
t = target + 1;\r
while (t < target_end) {\r
- if (*t != *p++)\r
- break;\r
- t++;\r
+ if (*t != *p++)\r
+ break;\r
+ t++;\r
}\r
if (t == target_end)\r
- return s;\r
+ return s;\r
}\r
s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);\r
}\r
\r
static UChar*\r
slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,\r
- UChar* target, UChar* target_end,\r
- const UChar* text, const UChar* adjust_text,\r
- const UChar* text_end, const UChar* text_start)\r
+ UChar* target, UChar* target_end,\r
+ const UChar* text, const UChar* adjust_text,\r
+ const UChar* text_end, const UChar* text_start)\r
{\r
UChar *s;\r
\r
\r
static UChar*\r
bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,\r
- const UChar* text, const UChar* text_end,\r
- const UChar* text_range)\r
+ const UChar* text, const UChar* text_end,\r
+ const UChar* text_range)\r
{\r
const UChar *s, *se, *t, *p, *end;\r
const UChar *tail;\r
int skip, tlen1;\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
- fprintf(stderr, "bm_search_notrev: text: %d, text_end: %d, text_range: %d\n",\r
- (int )text, (int )text_end, (int )text_range);\r
+ fprintf(stderr, "bm_search_notrev: text: %p, text_end: %p, text_range: %p\n",\r
+ text, text_end, text_range);\r
#endif\r
\r
tail = target_end - 1;\r
- tlen1 = (int)(tail - target);\r
+ tlen1 = (int )(tail - target);\r
end = text_range;\r
if (end + tlen1 > text_end)\r
end = text_end - tlen1;\r
p = se = s + tlen1;\r
t = tail;\r
while (*p == *t) {\r
- if (t == target) return (UChar* )s;\r
- p--; t--;\r
+ if (t == target) return (UChar* )s;\r
+ p--; t--;\r
}\r
skip = reg->map[*se];\r
t = s;\r
p = se = s + tlen1;\r
t = tail;\r
while (*p == *t) {\r
- if (t == target) return (UChar* )s;\r
- p--; t--;\r
+ if (t == target) return (UChar* )s;\r
+ p--; t--;\r
}\r
skip = reg->int_map[*se];\r
t = s;\r
\r
static UChar*\r
bm_search(regex_t* reg, const UChar* target, const UChar* target_end,\r
- const UChar* text, const UChar* text_end, const UChar* text_range)\r
+ const UChar* text, const UChar* text_end, const UChar* text_range)\r
{\r
const UChar *s, *t, *p, *end;\r
const UChar *tail;\r
p = s;\r
t = tail;\r
while (*p == *t) {\r
- if (t == target) return (UChar* )p;\r
- p--; t--;\r
+ if (t == target) return (UChar* )p;\r
+ p--; t--;\r
}\r
s += reg->map[*s];\r
}\r
p = s;\r
t = tail;\r
while (*p == *t) {\r
- if (t == target) return (UChar* )p;\r
- p--; t--;\r
+ if (t == target) return (UChar* )p;\r
+ p--; t--;\r
}\r
s += reg->int_map[*s];\r
}\r
return (UChar* )NULL;\r
}\r
\r
+#ifdef USE_INT_MAP_BACKWARD\r
static int\r
-set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,\r
- int** skip)\r
- \r
+set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED, int** skip)\r
{\r
int i, len;\r
\r
if (IS_NULL(*skip)) return ONIGERR_MEMORY;\r
}\r
\r
- len = (int)(end - s);\r
+ len = end - s;\r
for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)\r
(*skip)[i] = len;\r
\r
\r
static UChar*\r
bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,\r
- const UChar* text, const UChar* adjust_text,\r
- const UChar* text_end, const UChar* text_start)\r
+ const UChar* text, const UChar* adjust_text,\r
+ const UChar* text_end, const UChar* text_start)\r
{\r
const UChar *s, *t, *p;\r
\r
\r
return (UChar* )NULL;\r
}\r
+#endif\r
\r
static UChar*\r
map_search(OnigEncoding enc, UChar map[],\r
- const UChar* text, const UChar* text_range)\r
+ const UChar* text, const UChar* text_range)\r
{\r
const UChar *s = text;\r
\r
\r
static UChar*\r
map_search_backward(OnigEncoding enc, UChar map[],\r
- const UChar* text, const UChar* adjust_text,\r
- const UChar* text_start)\r
+ const UChar* text, const UChar* adjust_text,\r
+ const UChar* text_start)\r
{\r
const UChar *s = text_start;\r
\r
while (s >= text) {\r
+ //if text is not null,the logic is correct.\r
+ //this function is only invoked by backward_search_range,parameter text come\r
+ //from range, which is checked by "if (range == 0) goto fail" in line 4512\r
+ //so the check is just for passing static analysis.\r
+ if(IS_NULL(s))break;\r
if (map[*s]) return (UChar* )s;\r
\r
s = onigenc_get_prev_char_head(enc, adjust_text, s);\r
}\r
return (UChar* )NULL;\r
}\r
+extern int\r
+onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at,\r
+ OnigRegion* region, OnigOptionType option)\r
+{\r
+ int r;\r
+ OnigMatchParam mp;\r
+\r
+ onig_initialize_match_param(&mp);\r
+ r = onig_match_with_param(reg, str, end, at, region, option, &mp);\r
+ onig_free_match_param_content(&mp);\r
+ return r;\r
+}\r
\r
extern int\r
-onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, OnigRegion* region,\r
- OnigOptionType option)\r
+onig_match_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
+ const UChar* at, OnigRegion* region, OnigOptionType option,\r
+ OnigMatchParam* mp)\r
{\r
int r;\r
UChar *prev;\r
- OnigMatchArg msa;\r
-\r
-#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)\r
- start:\r
- THREAD_ATOMIC_START;\r
- if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {\r
- ONIG_STATE_INC(reg);\r
- if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {\r
- onig_chain_reduce(reg);\r
- ONIG_STATE_INC(reg);\r
- }\r
- }\r
- else {\r
- int n;\r
-\r
- THREAD_ATOMIC_END;\r
- n = 0;\r
- while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {\r
- if (++n > THREAD_PASS_LIMIT_COUNT)\r
- return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;\r
- THREAD_PASS;\r
- }\r
- goto start;\r
- }\r
- THREAD_ATOMIC_END;\r
-#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */\r
-\r
- MATCH_ARG_INIT(msa, option, region, at);\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- {\r
- int offset = at - str;\r
- STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);\r
- }\r
-#endif\r
+ MatchArg msa;\r
\r
+ ADJUST_MATCH_PARAM(reg, mp);\r
+ MATCH_ARG_INIT(msa, reg, option, region, at, mp);\r
if (region\r
#ifdef USE_POSIX_API_REGION_OPTION\r
&& !IS_POSIX_REGION(option)\r
r = 0;\r
\r
if (r == 0) {\r
+ if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
+ if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
+ r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
+ goto end;\r
+ }\r
+ }\r
+\r
prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at);\r
- r = match_at(reg, str, end,\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
- end,\r
-#endif\r
- at, prev, &msa);\r
+ r = match_at(reg, str, end, end, at, prev, &msa);\r
}\r
\r
+ end:\r
MATCH_ARG_FREE(msa);\r
- ONIG_STATE_DEC_THREAD(reg);\r
return r;\r
}\r
\r
static int\r
forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,\r
- UChar* range, UChar** low, UChar** high, UChar** low_prev)\r
+ UChar* range, UChar** low, UChar** high, UChar** low_prev)\r
{\r
UChar *p, *pprev = (UChar* )NULL;\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
- fprintf(stderr, "forward_search_range: str: %d, end: %d, s: %d, range: %d\n",\r
- (int )str, (int )end, (int )s, (int )range);\r
+ fprintf(stderr, "forward_search_range: str: %p, end: %p, s: %p, range: %p\n",\r
+ str, end, s, range);\r
#endif\r
\r
p = s;\r
}\r
else {\r
UChar *q = p + reg->dmin;\r
+\r
+ if (q >= end) return 0; /* fail */\r
while (p < q) p += enclen(reg->enc, p);\r
}\r
}\r
\r
retry:\r
switch (reg->optimize) {\r
- case ONIG_OPTIMIZE_EXACT:\r
+ case OPTIMIZE_EXACT:\r
p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);\r
break;\r
- case ONIG_OPTIMIZE_EXACT_IC:\r
+ case OPTIMIZE_EXACT_IC:\r
p = slow_search_ic(reg->enc, reg->case_fold_flag,\r
reg->exact, reg->exact_end, p, end, range);\r
break;\r
\r
- case ONIG_OPTIMIZE_EXACT_BM:\r
+ case OPTIMIZE_EXACT_BM:\r
p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);\r
break;\r
\r
- case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:\r
+ case OPTIMIZE_EXACT_BM_NO_REV:\r
p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);\r
break;\r
\r
- case ONIG_OPTIMIZE_MAP:\r
+ case OPTIMIZE_MAP:\r
p = map_search(reg->enc, reg->map, p, range);\r
break;\r
}\r
\r
switch (reg->sub_anchor) {\r
case ANCHOR_BEGIN_LINE:\r
- if (!ON_STR_BEGIN(p)) {\r
- prev = onigenc_get_prev_char_head(reg->enc,\r
- (pprev ? pprev : str), p);\r
- if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
- goto retry_gate;\r
- }\r
- break;\r
+ if (!ON_STR_BEGIN(p)) {\r
+ prev = onigenc_get_prev_char_head(reg->enc,\r
+ (pprev ? pprev : str), p);\r
+ if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
+ goto retry_gate;\r
+ }\r
+ break;\r
\r
case ANCHOR_END_LINE:\r
- if (ON_STR_END(p)) {\r
+ if (ON_STR_END(p)) {\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- prev = (UChar* )onigenc_get_prev_char_head(reg->enc,\r
- (pprev ? pprev : str), p);\r
- if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
- goto retry_gate;\r
+ prev = (UChar* )onigenc_get_prev_char_head(reg->enc,\r
+ (pprev ? pprev : str), p);\r
+ if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))\r
+ goto retry_gate;\r
#endif\r
- }\r
- else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
+ }\r
+ else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
- && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
+ && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
#endif\r
- )\r
- goto retry_gate;\r
- break;\r
+ )\r
+ goto retry_gate;\r
+ break;\r
}\r
}\r
\r
if (reg->dmax == 0) {\r
*low = p;\r
if (low_prev) {\r
- if (*low > s)\r
- *low_prev = onigenc_get_prev_char_head(reg->enc, s, p);\r
- else\r
- *low_prev = onigenc_get_prev_char_head(reg->enc,\r
- (pprev ? pprev : str), p);\r
+ if (*low > s)\r
+ *low_prev = onigenc_get_prev_char_head(reg->enc, s, p);\r
+ else\r
+ *low_prev = onigenc_get_prev_char_head(reg->enc,\r
+ (pprev ? pprev : str), p);\r
}\r
}\r
else {\r
- if (reg->dmax != ONIG_INFINITE_DISTANCE) {\r
- *low = p - reg->dmax;\r
- if (*low > s) {\r
- *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,\r
- *low, (const UChar** )low_prev);\r
- if (low_prev && IS_NULL(*low_prev))\r
- *low_prev = onigenc_get_prev_char_head(reg->enc,\r
- (pprev ? pprev : s), *low);\r
- }\r
- else {\r
- if (low_prev)\r
- *low_prev = onigenc_get_prev_char_head(reg->enc,\r
- (pprev ? pprev : str), *low);\r
- }\r
+ if (reg->dmax != INFINITE_LEN) {\r
+ if (p - str < reg->dmax) {\r
+ *low = (UChar* )str;\r
+ if (low_prev)\r
+ *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);\r
+ }\r
+ else {\r
+ *low = p - reg->dmax;\r
+ if (*low > s) {\r
+ *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,\r
+ *low, (const UChar** )low_prev);\r
+ if (low_prev && IS_NULL(*low_prev))\r
+ *low_prev = onigenc_get_prev_char_head(reg->enc,\r
+ (pprev ? pprev : s), *low);\r
+ }\r
+ else {\r
+ if (low_prev)\r
+ *low_prev = onigenc_get_prev_char_head(reg->enc,\r
+ (pprev ? pprev : str), *low);\r
+ }\r
+ }\r
}\r
}\r
/* no needs to adjust *high, *high is used as range check only */\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
fprintf(stderr,\r
- "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",\r
- (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);\r
+ "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",\r
+ (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);\r
#endif\r
return 1; /* success */\r
}\r
return 0; /* fail */\r
}\r
\r
-static int set_bm_backward_skip P_((UChar* s, UChar* end, OnigEncoding enc,\r
- int** skip));\r
\r
#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100\r
\r
static int\r
backward_search_range(regex_t* reg, const UChar* str, const UChar* end,\r
- UChar* s, const UChar* range, UChar* adjrange,\r
- UChar** low, UChar** high)\r
+ UChar* s, const UChar* range, UChar* adjrange,\r
+ UChar** low, UChar** high)\r
{\r
- int r;\r
UChar *p;\r
-\r
+ if (range == 0) goto fail;\r
range += reg->dmin;\r
p = s;\r
\r
retry:\r
switch (reg->optimize) {\r
- case ONIG_OPTIMIZE_EXACT:\r
+ case OPTIMIZE_EXACT:\r
exact_method:\r
p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,\r
- range, adjrange, end, p);\r
+ range, adjrange, end, p);\r
break;\r
\r
- case ONIG_OPTIMIZE_EXACT_IC:\r
+ case OPTIMIZE_EXACT_IC:\r
p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,\r
reg->exact, reg->exact_end,\r
range, adjrange, end, p);\r
break;\r
\r
- case ONIG_OPTIMIZE_EXACT_BM:\r
- case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:\r
+ case OPTIMIZE_EXACT_BM:\r
+ case OPTIMIZE_EXACT_BM_NO_REV:\r
+#ifdef USE_INT_MAP_BACKWARD\r
if (IS_NULL(reg->int_map_backward)) {\r
+ int r;\r
+\r
if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)\r
- goto exact_method;\r
+ goto exact_method;\r
\r
r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,\r
- &(reg->int_map_backward));\r
- if (r) return r;\r
+ &(reg->int_map_backward));\r
+ if (r != 0) return r;\r
}\r
p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,\r
- end, p);\r
+ end, p);\r
+#else\r
+ goto exact_method;\r
+#endif\r
break;\r
\r
- case ONIG_OPTIMIZE_MAP:\r
+ case OPTIMIZE_MAP:\r
p = map_search_backward(reg->enc, reg->map, range, adjrange, p);\r
break;\r
}\r
\r
switch (reg->sub_anchor) {\r
case ANCHOR_BEGIN_LINE:\r
- if (!ON_STR_BEGIN(p)) {\r
- prev = onigenc_get_prev_char_head(reg->enc, str, p);\r
- if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
- p = prev;\r
- goto retry;\r
- }\r
- }\r
- break;\r
+ if (!ON_STR_BEGIN(p)) {\r
+ prev = onigenc_get_prev_char_head(reg->enc, str, p);\r
+ if (IS_NOT_NULL(prev) && !ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
+ p = prev;\r
+ goto retry;\r
+ }\r
+ }\r
+ break;\r
\r
case ANCHOR_END_LINE:\r
- if (ON_STR_END(p)) {\r
+ if (ON_STR_END(p)) {\r
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE\r
- prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
- if (IS_NULL(prev)) goto fail;\r
- if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
- p = prev;\r
- goto retry;\r
- }\r
-#endif\r
- }\r
- else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
+ prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
+ if (IS_NULL(prev)) goto fail;\r
+ if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {\r
+ p = prev;\r
+ goto retry;\r
+ }\r
+#endif\r
+ }\r
+ else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
- && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
+ && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)\r
#endif\r
- ) {\r
- p = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
- if (IS_NULL(p)) goto fail;\r
- goto retry;\r
- }\r
- break;\r
+ ) {\r
+ p = onigenc_get_prev_char_head(reg->enc, adjrange, p);\r
+ if (IS_NULL(p)) goto fail;\r
+ goto retry;\r
+ }\r
+ break;\r
}\r
}\r
\r
/* no needs to adjust *high, *high is used as range check only */\r
- if (reg->dmax != ONIG_INFINITE_DISTANCE) {\r
+ if (reg->dmax != INFINITE_LEN) {\r
*low = p - reg->dmax;\r
*high = p - reg->dmin;\r
*high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high);\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
fprintf(stderr, "backward_search_range: low: %d, high: %d\n",\r
- (int )(*low - str), (int )(*high - str));\r
+ (int )(*low - str), (int )(*high - str));\r
#endif\r
return 1; /* success */\r
}\r
\r
extern int\r
onig_search(regex_t* reg, const UChar* str, const UChar* end,\r
- const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)\r
+ const UChar* start, const UChar* range, OnigRegion* region,\r
+ OnigOptionType option)\r
+{\r
+ int r;\r
+ OnigMatchParam mp;\r
+\r
+ onig_initialize_match_param(&mp);\r
+ r = onig_search_with_param(reg, str, end, start, range, region, option, &mp);\r
+ onig_free_match_param_content(&mp);\r
+ return r;\r
+\r
+}\r
+\r
+extern int\r
+onig_search_with_param(regex_t* reg, const UChar* str, const UChar* end,\r
+ const UChar* start, const UChar* range, OnigRegion* region,\r
+ OnigOptionType option, OnigMatchParam* mp)\r
{\r
int r;\r
UChar *s, *prev;\r
- OnigMatchArg msa;\r
+ MatchArg msa;\r
const UChar *orig_start = start;\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
const UChar *orig_range = range;\r
-#endif\r
-\r
-#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)\r
- start:\r
- THREAD_ATOMIC_START;\r
- if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {\r
- ONIG_STATE_INC(reg);\r
- if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {\r
- onig_chain_reduce(reg);\r
- ONIG_STATE_INC(reg);\r
- }\r
- }\r
- else {\r
- int n;\r
-\r
- THREAD_ATOMIC_END;\r
- n = 0;\r
- while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {\r
- if (++n > THREAD_PASS_LIMIT_COUNT)\r
- return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;\r
- THREAD_PASS;\r
- }\r
- goto start;\r
- }\r
- THREAD_ATOMIC_END;\r
-#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
fprintf(stderr,\r
- "onig_search (entry point): str: %d, end: %d, start: %d, range: %d\n",\r
- (int )str, (int )(end - str), (int )(start - str), (int )(range - str));\r
+ "onig_search (entry point): str: %p, end: %d, start: %d, range: %d\n",\r
+ str, (int )(end - str), (int )(start - str), (int )(range - str));\r
#endif\r
\r
+ ADJUST_MATCH_PARAM(reg, mp);\r
+\r
if (region\r
#ifdef USE_POSIX_API_REGION_OPTION\r
&& !IS_POSIX_REGION(option)\r
#endif\r
) {\r
r = onig_region_resize_clear(region, reg->num_mem + 1);\r
- if (r) goto finish_no_msa;\r
+ if (r != 0) goto finish_no_msa;\r
}\r
\r
if (start > end || start < str) goto mismatch_no_msa;\r
\r
+ if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
+ if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end)) {\r
+ r = ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
+ goto finish_no_msa;\r
+ }\r
+ }\r
+\r
\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
#define MATCH_AND_RETURN_CHECK(upper_range) \\r
r = match_at(reg, str, end, (upper_range), s, prev, &msa); \\r
else goto finish; /* error */ \\r
}\r
#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */\r
-#else\r
-#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE\r
-#define MATCH_AND_RETURN_CHECK(none) \\r
- r = match_at(reg, str, end, s, prev, &msa);\\r
- if (r != ONIG_MISMATCH) {\\r
- if (r >= 0) {\\r
- if (! IS_FIND_LONGEST(reg->options)) {\\r
- goto match;\\r
- }\\r
- }\\r
- else goto finish; /* error */ \\r
- }\r
-#else\r
-#define MATCH_AND_RETURN_CHECK(none) \\r
- r = match_at(reg, str, end, s, prev, &msa);\\r
- if (r != ONIG_MISMATCH) {\\r
- if (r >= 0) {\\r
- goto match;\\r
- }\\r
- else goto finish; /* error */ \\r
- }\r
-#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */\r
-#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */\r
\r
\r
/* anchor optimize: resume search range */\r
/* search start-position only */\r
begin_position:\r
if (range > start)\r
- range = start + 1;\r
+ range = start + 1;\r
else\r
- range = start;\r
+ range = start;\r
}\r
else if (reg->anchor & ANCHOR_BEGIN_BUF) {\r
/* search str-position only */\r
if (range > start) {\r
- if (start != str) goto mismatch_no_msa;\r
- range = str + 1;\r
+ if (start != str) goto mismatch_no_msa;\r
+ range = str + 1;\r
}\r
else {\r
- if (range <= str) {\r
- start = str;\r
- range = str;\r
- }\r
- else\r
- goto mismatch_no_msa;\r
+ if (range <= str) {\r
+ start = str;\r
+ range = str;\r
+ }\r
+ else\r
+ goto mismatch_no_msa;\r
}\r
}\r
else if (reg->anchor & ANCHOR_END_BUF) {\r
min_semi_end = max_semi_end = (UChar* )end;\r
\r
end_buf:\r
- if ((OnigDistance )(max_semi_end - str) < reg->anchor_dmin)\r
- goto mismatch_no_msa;\r
+ if ((OnigLen )(max_semi_end - str) < reg->anchor_dmin)\r
+ goto mismatch_no_msa;\r
\r
if (range > start) {\r
- if ((OnigDistance )(min_semi_end - start) > reg->anchor_dmax) {\r
- start = min_semi_end - reg->anchor_dmax;\r
- if (start < end)\r
- start = onigenc_get_right_adjust_char_head(reg->enc, str, start);\r
- else { /* match with empty at end */\r
- start = onigenc_get_prev_char_head(reg->enc, str, end);\r
- }\r
- }\r
- if ((OnigDistance )(max_semi_end - (range - 1)) < reg->anchor_dmin) {\r
- range = max_semi_end - reg->anchor_dmin + 1;\r
- }\r
-\r
- if (start >= range) goto mismatch_no_msa;\r
+ if ((OnigLen )(min_semi_end - start) > reg->anchor_dmax) {\r
+ start = min_semi_end - reg->anchor_dmax;\r
+ if (start < end)\r
+ start = onigenc_get_right_adjust_char_head(reg->enc, str, start);\r
+ }\r
+ if ((OnigLen )(max_semi_end - (range - 1)) < reg->anchor_dmin) {\r
+ range = max_semi_end - reg->anchor_dmin + 1;\r
+ }\r
+\r
+ if (start > range) goto mismatch_no_msa;\r
+ /* If start == range, match with empty at end.\r
+ Backward search is used. */\r
}\r
else {\r
- if ((OnigDistance )(min_semi_end - range) > reg->anchor_dmax) {\r
- range = min_semi_end - reg->anchor_dmax;\r
- }\r
- if ((OnigDistance )(max_semi_end - start) < reg->anchor_dmin) {\r
- start = max_semi_end - reg->anchor_dmin;\r
- start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start);\r
- }\r
- if (range > start) goto mismatch_no_msa;\r
+ if ((OnigLen )(min_semi_end - range) > reg->anchor_dmax) {\r
+ range = min_semi_end - reg->anchor_dmax;\r
+ }\r
+ if ((OnigLen )(max_semi_end - start) < reg->anchor_dmin) {\r
+ start = max_semi_end - reg->anchor_dmin;\r
+ start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start);\r
+ }\r
+ if (range > start) goto mismatch_no_msa;\r
}\r
}\r
else if (reg->anchor & ANCHOR_SEMI_END_BUF) {\r
+\r
UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, 1);\r
\r
max_semi_end = (UChar* )end;\r
- if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {\r
- min_semi_end = pre_end;\r
+ // only when str > end, pre_end will be null\r
+ // line 4659 "if (start > end || start < str) goto mismatch_no_msa"\r
+ // will guarantee str alwayls less than end\r
+ // so pre_end won't be null,this check is just for passing staic analysis\r
+ if (IS_NOT_NULL(pre_end) && ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {\r
+ min_semi_end = pre_end;\r
\r
#ifdef USE_CRNL_AS_LINE_TERMINATOR\r
- pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, 1);\r
- if (IS_NOT_NULL(pre_end) &&\r
- ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {\r
- min_semi_end = pre_end;\r
- }\r
+ pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, 1);\r
+ if (IS_NOT_NULL(pre_end) &&\r
+ ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {\r
+ min_semi_end = pre_end;\r
+ }\r
#endif\r
- if (min_semi_end > str && start <= min_semi_end) {\r
- goto end_buf;\r
- }\r
+ if (min_semi_end > str && start <= min_semi_end) {\r
+ goto end_buf;\r
+ }\r
}\r
else {\r
- min_semi_end = (UChar* )end;\r
- goto end_buf;\r
+ min_semi_end = (UChar* )end;\r
+ goto end_buf;\r
}\r
}\r
- else if ((reg->anchor & ANCHOR_ANYCHAR_STAR_ML)) {\r
+ else if ((reg->anchor & ANCHOR_ANYCHAR_INF_ML)) {\r
goto begin_position;\r
}\r
}\r
s = (UChar* )start;\r
prev = (UChar* )NULL;\r
\r
- MATCH_ARG_INIT(msa, option, region, start);\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- msa.state_check_buff = (void* )0;\r
- msa.state_check_buff_size = 0; /* NO NEED, for valgrind */\r
-#endif\r
+ MATCH_ARG_INIT(msa, reg, option, region, start, mp);\r
MATCH_AND_RETURN_CHECK(end);\r
goto mismatch;\r
}\r
\r
#ifdef ONIG_DEBUG_SEARCH\r
fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",\r
- (int )(end - str), (int )(start - str), (int )(range - str));\r
+ (int )(end - str), (int )(start - str), (int )(range - str));\r
#endif\r
\r
- MATCH_ARG_INIT(msa, option, region, orig_start);\r
-#ifdef USE_COMBINATION_EXPLOSION_CHECK\r
- {\r
- int offset = (MIN(start, range) - str);\r
- STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);\r
- }\r
-#endif\r
+ MATCH_ARG_INIT(msa, reg, option, region, orig_start, mp);\r
\r
s = (UChar* )start;\r
if (range > start) { /* forward search */\r
else\r
prev = (UChar* )NULL;\r
\r
- if (reg->optimize != ONIG_OPTIMIZE_NONE) {\r
+ if (reg->optimize != OPTIMIZE_NONE) {\r
UChar *sch_range, *low, *high, *low_prev;\r
\r
sch_range = (UChar* )range;\r
if (reg->dmax != 0) {\r
- if (reg->dmax == ONIG_INFINITE_DISTANCE)\r
- sch_range = (UChar* )end;\r
- else {\r
- sch_range += reg->dmax;\r
- if (sch_range > end) sch_range = (UChar* )end;\r
- }\r
+ if (reg->dmax == INFINITE_LEN)\r
+ sch_range = (UChar* )end;\r
+ else {\r
+ sch_range += reg->dmax;\r
+ if (sch_range > end) sch_range = (UChar* )end;\r
+ }\r
}\r
\r
if ((end - start) < reg->threshold_len)\r
goto mismatch;\r
\r
- if (reg->dmax != ONIG_INFINITE_DISTANCE) {\r
- do {\r
- if (! forward_search_range(reg, str, end, s, sch_range,\r
- &low, &high, &low_prev)) goto mismatch;\r
- if (s < low) {\r
- s = low;\r
- prev = low_prev;\r
- }\r
- while (s <= high) {\r
- MATCH_AND_RETURN_CHECK(orig_range);\r
- prev = s;\r
- s += enclen(reg->enc, s);\r
- }\r
- } while (s < range);\r
- goto mismatch;\r
+ if (reg->dmax != INFINITE_LEN) {\r
+ do {\r
+ if (! forward_search_range(reg, str, end, s, sch_range,\r
+ &low, &high, &low_prev)) goto mismatch;\r
+ if (s < low) {\r
+ s = low;\r
+ prev = low_prev;\r
+ }\r
+ while (s <= high) {\r
+ MATCH_AND_RETURN_CHECK(orig_range);\r
+ prev = s;\r
+ s += enclen(reg->enc, s);\r
+ }\r
+ } while (s < range);\r
+ goto mismatch;\r
}\r
else { /* check only. */\r
- if (! forward_search_range(reg, str, end, s, sch_range,\r
- &low, &high, (UChar** )NULL)) goto mismatch;\r
+ if (! forward_search_range(reg, str, end, s, sch_range,\r
+ &low, &high, (UChar** )NULL)) goto mismatch;\r
\r
- if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {\r
+ if ((reg->anchor & ANCHOR_ANYCHAR_INF) != 0) {\r
do {\r
MATCH_AND_RETURN_CHECK(orig_range);\r
prev = s;\r
s += enclen(reg->enc, s);\r
\r
- while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {\r
- prev = s;\r
- s += enclen(reg->enc, s);\r
+ if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {\r
+ while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {\r
+ prev = s;\r
+ s += enclen(reg->enc, s);\r
+ }\r
}\r
} while (s < range);\r
goto mismatch;\r
}\r
}\r
else { /* backward search */\r
-#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE\r
if (orig_start < end)\r
orig_start += enclen(reg->enc, orig_start); /* is upper range */\r
-#endif\r
\r
- if (reg->optimize != ONIG_OPTIMIZE_NONE) {\r
+ if (reg->optimize != OPTIMIZE_NONE) {\r
UChar *low, *high, *adjrange, *sch_start;\r
\r
if (range < end)\r
- adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range);\r
+ adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range);\r
else\r
- adjrange = (UChar* )end;\r
-\r
- if (reg->dmax != ONIG_INFINITE_DISTANCE &&\r
- (end - range) >= reg->threshold_len) {\r
- do {\r
- sch_start = s + reg->dmax;\r
- if (sch_start > end) sch_start = (UChar* )end;\r
- if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
- &low, &high) <= 0)\r
- goto mismatch;\r
-\r
- if (s > high)\r
- s = high;\r
-\r
- while (s >= low) {\r
- prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
- MATCH_AND_RETURN_CHECK(orig_start);\r
- s = prev;\r
- }\r
- } while (s >= range);\r
- goto mismatch;\r
+ adjrange = (UChar* )end;\r
+\r
+ if (reg->dmax != INFINITE_LEN &&\r
+ (end - range) >= reg->threshold_len) {\r
+ do {\r
+ sch_start = s + reg->dmax;\r
+ if (sch_start > end) sch_start = (UChar* )end;\r
+ if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
+ &low, &high) <= 0)\r
+ goto mismatch;\r
+\r
+ if (s > high)\r
+ s = high;\r
+\r
+ while (s >= low) {\r
+ prev = onigenc_get_prev_char_head(reg->enc, str, s);\r
+ MATCH_AND_RETURN_CHECK(orig_start);\r
+ s = prev;\r
+ }\r
+ // if range is not null,the check is not necessary.\r
+ // the range is actually the pointer of the end of the matched string\r
+ // or assigned by "range = str" in line 4708. In RegularExpressionMatch\r
+ // protocol, the matched string is the parameter String. And str in\r
+ // line 4708 is the String,too. and the range is calculated from\r
+ // "Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start)" in\r
+ // line 146 in RegularExpressionDxe.c. RegularExpressionMatch ensure\r
+ // the String is not null,So in both situation, the range can not be NULL.\r
+ // This check is just for passing static analysis.\r
+ if(IS_NULL(s))break;\r
+ } while (s >= range);\r
+ goto mismatch;\r
}\r
else { /* check only. */\r
- if ((end - range) < reg->threshold_len) goto mismatch;\r
-\r
- sch_start = s;\r
- if (reg->dmax != 0) {\r
- if (reg->dmax == ONIG_INFINITE_DISTANCE)\r
- sch_start = (UChar* )end;\r
- else {\r
- sch_start += reg->dmax;\r
- if (sch_start > end) sch_start = (UChar* )end;\r
- else\r
- sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,\r
- start, sch_start);\r
- }\r
- }\r
- if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
- &low, &high) <= 0) goto mismatch;\r
+ if ((end - range) < reg->threshold_len) goto mismatch;\r
+\r
+ sch_start = s;\r
+ if (reg->dmax != 0) {\r
+ if (reg->dmax == INFINITE_LEN)\r
+ sch_start = (UChar* )end;\r
+ else {\r
+ sch_start += reg->dmax;\r
+ if (sch_start > end) sch_start = (UChar* )end;\r
+ else\r
+ sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,\r
+ start, sch_start);\r
+ }\r
+ }\r
+ if (backward_search_range(reg, str, end, sch_start, range, adjrange,\r
+ &low, &high) <= 0) goto mismatch;\r
}\r
}\r
\r
\r
finish:\r
MATCH_ARG_FREE(msa);\r
- ONIG_STATE_DEC_THREAD(reg);\r
\r
/* If result is mismatch and no FIND_NOT_EMPTY option,\r
- then the region is not setted in match_at(). */\r
+ then the region is not set in match_at(). */\r
if (IS_FIND_NOT_EMPTY(reg->options) && region\r
#ifdef USE_POSIX_API_REGION_OPTION\r
&& !IS_POSIX_REGION(option)\r
mismatch_no_msa:\r
r = ONIG_MISMATCH;\r
finish_no_msa:\r
- ONIG_STATE_DEC_THREAD(reg);\r
#ifdef ONIG_DEBUG\r
if (r != ONIG_MISMATCH)\r
fprintf(stderr, "onig_search: error %d\n", r);\r
return r;\r
\r
match:\r
- ONIG_STATE_DEC_THREAD(reg);\r
MATCH_ARG_FREE(msa);\r
- return (int)(s - str);\r
+ return (int )(s - str);\r
+}\r
+\r
+extern int\r
+onig_scan(regex_t* reg, const UChar* str, const UChar* end,\r
+ OnigRegion* region, OnigOptionType option,\r
+ int (*scan_callback)(int, int, OnigRegion*, void*),\r
+ void* callback_arg)\r
+{\r
+ int r;\r
+ int n;\r
+ int rs;\r
+ const UChar* start;\r
+\r
+ if (ONIG_IS_OPTION_ON(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING)) {\r
+ if (! ONIGENC_IS_VALID_MBC_STRING(reg->enc, str, end))\r
+ return ONIGERR_INVALID_WIDE_CHAR_VALUE;\r
+\r
+ ONIG_OPTION_OFF(option, ONIG_OPTION_CHECK_VALIDITY_OF_STRING);\r
+ }\r
+\r
+ n = 0;\r
+ start = str;\r
+ while (1) {\r
+ r = onig_search(reg, str, end, start, end, region, option);\r
+ if (r >= 0) {\r
+ rs = scan_callback(n, r, region, callback_arg);\r
+ n++;\r
+ if (rs != 0)\r
+ return rs;\r
+\r
+ if (region->end[0] == start - str) {\r
+ if (start >= end) break;\r
+ start += enclen(reg->enc, start);\r
+ }\r
+ else\r
+ start = str + region->end[0];\r
+\r
+ if (start > end)\r
+ break;\r
+ }\r
+ else if (r == ONIG_MISMATCH) {\r
+ break;\r
+ }\r
+ else { /* error */\r
+ return r;\r
+ }\r
+ }\r
+\r
+ return n;\r
}\r
\r
extern OnigEncoding\r
\r
n = 0;\r
for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {\r
- if (BIT_STATUS_AT(reg->capture_history, i) != 0)\r
+ if (MEM_STATUS_AT(reg->capture_history, i) != 0)\r
n++;\r
}\r
return n;\r
*to = *from;\r
}\r
\r
+\r
+/* for callout functions */\r
+\r
+#ifdef USE_CALLOUT\r
+\r
+extern OnigCalloutFunc\r
+onig_get_progress_callout(void)\r
+{\r
+ return DefaultProgressCallout;\r
+}\r
+\r
+extern int\r
+onig_set_progress_callout(OnigCalloutFunc f)\r
+{\r
+ DefaultProgressCallout = f;\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern OnigCalloutFunc\r
+onig_get_retraction_callout(void)\r
+{\r
+ return DefaultRetractionCallout;\r
+}\r
+\r
+extern int\r
+onig_set_retraction_callout(OnigCalloutFunc f)\r
+{\r
+ DefaultRetractionCallout = f;\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern int\r
+onig_get_callout_num_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->num;\r
+}\r
+\r
+extern OnigCalloutIn\r
+onig_get_callout_in_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->in;\r
+}\r
+\r
+extern int\r
+onig_get_name_id_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->name_id;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_contents_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ int num;\r
+ CalloutListEntry* e;\r
+\r
+ num = args->num;\r
+ e = onig_reg_callout_list_at(args->regex, num);\r
+ if (IS_NULL(e)) return 0;\r
+ if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
+ return e->u.content.start;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_contents_end_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ int num;\r
+ CalloutListEntry* e;\r
+\r
+ num = args->num;\r
+ e = onig_reg_callout_list_at(args->regex, num);\r
+ if (IS_NULL(e)) return 0;\r
+ if (e->of == ONIG_CALLOUT_OF_CONTENTS) {\r
+ return e->u.content.end;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+extern int\r
+onig_get_args_num_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ int num;\r
+ CalloutListEntry* e;\r
+\r
+ num = args->num;\r
+ e = onig_reg_callout_list_at(args->regex, num);\r
+ if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
+ if (e->of == ONIG_CALLOUT_OF_NAME) {\r
+ return e->u.arg.num;\r
+ }\r
+\r
+ return ONIGERR_INVALID_ARGUMENT;\r
+}\r
+\r
+extern int\r
+onig_get_passed_args_num_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ int num;\r
+ CalloutListEntry* e;\r
+\r
+ num = args->num;\r
+ e = onig_reg_callout_list_at(args->regex, num);\r
+ if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
+ if (e->of == ONIG_CALLOUT_OF_NAME) {\r
+ return e->u.arg.passed_num;\r
+ }\r
+\r
+ return ONIGERR_INVALID_ARGUMENT;\r
+}\r
+\r
+extern int\r
+onig_get_arg_by_callout_args(OnigCalloutArgs* args, int index,\r
+ OnigType* type, OnigValue* val)\r
+{\r
+ int num;\r
+ CalloutListEntry* e;\r
+\r
+ num = args->num;\r
+ e = onig_reg_callout_list_at(args->regex, num);\r
+ if (IS_NULL(e)) return ONIGERR_INVALID_ARGUMENT;\r
+ if (e->of == ONIG_CALLOUT_OF_NAME) {\r
+ if (IS_NOT_NULL(type)) *type = e->u.arg.types[index];\r
+ if (IS_NOT_NULL(val)) *val = e->u.arg.vals[index];\r
+ return ONIG_NORMAL;\r
+ }\r
+\r
+ return ONIGERR_INVALID_ARGUMENT;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_string_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->string;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_string_end_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->string_end;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_start_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->start;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_right_range_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->right_range;\r
+}\r
+\r
+extern const UChar*\r
+onig_get_current_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->current;\r
+}\r
+\r
+extern OnigRegex\r
+onig_get_regex_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->regex;\r
+}\r
+\r
+extern unsigned long\r
+onig_get_retry_counter_by_callout_args(OnigCalloutArgs* args)\r
+{\r
+ return args->retry_in_match_counter;\r
+}\r
+\r
+\r
+extern int\r
+onig_get_capture_range_in_callout(OnigCalloutArgs* a, int mem_num, int* begin, int* end)\r
+{\r
+ OnigRegex reg;\r
+ const UChar* str;\r
+ StackType* stk_base;\r
+ int i;\r
+\r
+ i = mem_num;\r
+ reg = a->regex;\r
+ str = a->string;\r
+ stk_base = a->stk_base;\r
+\r
+ if (i > 0) {\r
+ if (a->mem_end_stk[i] != INVALID_STACK_INDEX) {\r
+ if (MEM_STATUS_AT(reg->bt_mem_start, i))\r
+ *begin = (int )(STACK_AT(a->mem_start_stk[i])->u.mem.pstr - str);\r
+ else\r
+ *begin = (int )((UChar* )((void* )a->mem_start_stk[i]) - str);\r
+\r
+ *end = (int )((MEM_STATUS_AT(reg->bt_mem_end, i)\r
+ ? STACK_AT(a->mem_end_stk[i])->u.mem.pstr\r
+ : (UChar* )((void* )a->mem_end_stk[i])) - str);\r
+ }\r
+ else {\r
+ *begin = *end = ONIG_REGION_NOTPOS;\r
+ }\r
+ }\r
+ else if (i == 0) {\r
+#if 0\r
+ *begin = a->start - str;\r
+ *end = a->current - str;\r
+#else\r
+ return ONIGERR_INVALID_ARGUMENT;\r
+#endif\r
+ }\r
+ else\r
+ return ONIGERR_INVALID_ARGUMENT;\r
+\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+extern int\r
+onig_get_used_stack_size_in_callout(OnigCalloutArgs* a, int* used_num, int* used_bytes)\r
+{\r
+ int n;\r
+\r
+ n = (int )(a->stk - a->stk_base);\r
+\r
+ if (used_num != 0)\r
+ *used_num = n;\r
+\r
+ if (used_bytes != 0)\r
+ *used_bytes = n * sizeof(StackType);\r
+\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+\r
+/* builtin callout functions */\r
+\r
+extern int\r
+onig_builtin_fail(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
+{\r
+ return ONIG_CALLOUT_FAIL;\r
+}\r
+\r
+extern int\r
+onig_builtin_mismatch(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
+{\r
+ return ONIG_MISMATCH;\r
+}\r
+\r
+#if 0\r
+extern int\r
+onig_builtin_success(OnigCalloutArgs* args ARG_UNUSED, void* user_data ARG_UNUSED)\r
+{\r
+ return ONIG_CALLOUT_SUCCESS;\r
+}\r
+#endif\r
+\r
+extern int\r
+onig_builtin_error(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
+{\r
+ int r;\r
+ int n;\r
+ OnigValue val;\r
+\r
+ r = onig_get_arg_by_callout_args(args, 0, 0, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ n = (int )val.l;\r
+ if (n >= 0) {\r
+ n = ONIGERR_INVALID_CALLOUT_BODY;\r
+ }\r
+\r
+ return n;\r
+}\r
+\r
+extern int\r
+onig_builtin_count(OnigCalloutArgs* args, void* user_data)\r
+{\r
+ (void )onig_check_callout_data_and_clear_old_values(args);\r
+\r
+ return onig_builtin_total_count(args, user_data);\r
+}\r
+\r
+extern int\r
+onig_builtin_total_count(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
+{\r
+ int r;\r
+ int slot;\r
+ OnigType type;\r
+ OnigValue val;\r
+ OnigValue aval;\r
+ OnigCodePoint count_type;\r
+\r
+ r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ count_type = aval.c;\r
+ if (count_type != '>' && count_type != 'X' && count_type != '<')\r
+ return ONIGERR_INVALID_CALLOUT_ARG;\r
+\r
+ r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, 0,\r
+ &type, &val);\r
+ if (r < ONIG_NORMAL)\r
+ return r;\r
+ else if (r > ONIG_NORMAL) {\r
+ /* type == void: initial state */\r
+ val.l = 0;\r
+ }\r
+\r
+ if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
+ slot = 2;\r
+ if (count_type == '<')\r
+ val.l++;\r
+ else if (count_type == 'X')\r
+ val.l--;\r
+ }\r
+ else {\r
+ slot = 1;\r
+ if (count_type != '<')\r
+ val.l++;\r
+ }\r
+\r
+ r = onig_set_callout_data_by_callout_args_self(args, 0, ONIG_TYPE_LONG, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ /* slot 1: in progress counter, slot 2: in retraction counter */\r
+ r = onig_get_callout_data_by_callout_args_self_dont_clear_old(args, slot,\r
+ &type, &val);\r
+ if (r < ONIG_NORMAL)\r
+ return r;\r
+ else if (r > ONIG_NORMAL) {\r
+ val.l = 0;\r
+ }\r
+\r
+ val.l++;\r
+ r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ return ONIG_CALLOUT_SUCCESS;\r
+}\r
+\r
+extern int\r
+onig_builtin_max(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
+{\r
+ int r;\r
+ int slot;\r
+ long max_val;\r
+ OnigCodePoint count_type;\r
+ OnigType type;\r
+ OnigValue val;\r
+ OnigValue aval;\r
+\r
+ (void )onig_check_callout_data_and_clear_old_values(args);\r
+\r
+ slot = 0;\r
+ r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
+ if (r < ONIG_NORMAL)\r
+ return r;\r
+ else if (r > ONIG_NORMAL) {\r
+ /* type == void: initial state */\r
+ type = ONIG_TYPE_LONG;\r
+ val.l = 0;\r
+ }\r
+\r
+ r = onig_get_arg_by_callout_args(args, 0, &type, &aval);\r
+ if (r != ONIG_NORMAL) return r;\r
+ if (type == ONIG_TYPE_TAG) {\r
+ r = onig_get_callout_data_by_callout_args(args, aval.tag, 0, &type, &aval);\r
+ if (r < ONIG_NORMAL) return r;\r
+ else if (r > ONIG_NORMAL)\r
+ max_val = 0L;\r
+ else\r
+ max_val = aval.l;\r
+ }\r
+ else { /* LONG */\r
+ max_val = aval.l;\r
+ }\r
+\r
+ r = onig_get_arg_by_callout_args(args, 1, &type, &aval);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ count_type = aval.c;\r
+ if (count_type != '>' && count_type != 'X' && count_type != '<')\r
+ return ONIGERR_INVALID_CALLOUT_ARG;\r
+\r
+ if (args->in == ONIG_CALLOUT_IN_RETRACTION) {\r
+ if (count_type == '<') {\r
+ if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
+ val.l++;\r
+ }\r
+ else if (count_type == 'X')\r
+ val.l--;\r
+ }\r
+ else {\r
+ if (count_type != '<') {\r
+ if (val.l >= max_val) return ONIG_CALLOUT_FAIL;\r
+ val.l++;\r
+ }\r
+ }\r
+\r
+ r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ return ONIG_CALLOUT_SUCCESS;\r
+}\r
+\r
+enum OP_CMP {\r
+ OP_EQ,\r
+ OP_NE,\r
+ OP_LT,\r
+ OP_GT,\r
+ OP_LE,\r
+ OP_GE\r
+};\r
+\r
+extern int\r
+onig_builtin_cmp(OnigCalloutArgs* args, void* user_data ARG_UNUSED)\r
+{\r
+ int r;\r
+ int slot;\r
+ long lv;\r
+ long rv;\r
+ OnigType type;\r
+ OnigValue val;\r
+ regex_t* reg;\r
+ enum OP_CMP op;\r
+\r
+ reg = args->regex;\r
+\r
+ r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ if (type == ONIG_TYPE_TAG) {\r
+ r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
+ if (r < ONIG_NORMAL) return r;\r
+ else if (r > ONIG_NORMAL)\r
+ lv = 0L;\r
+ else\r
+ lv = val.l;\r
+ }\r
+ else { /* ONIG_TYPE_LONG */\r
+ lv = val.l;\r
+ }\r
+\r
+ r = onig_get_arg_by_callout_args(args, 2, &type, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ if (type == ONIG_TYPE_TAG) {\r
+ r = onig_get_callout_data_by_callout_args(args, val.tag, 0, &type, &val);\r
+ if (r < ONIG_NORMAL) return r;\r
+ else if (r > ONIG_NORMAL)\r
+ rv = 0L;\r
+ else\r
+ rv = val.l;\r
+ }\r
+ else { /* ONIG_TYPE_LONG */\r
+ rv = val.l;\r
+ }\r
+\r
+ slot = 0;\r
+ r = onig_get_callout_data_by_callout_args_self(args, slot, &type, &val);\r
+ if (r < ONIG_NORMAL)\r
+ return r;\r
+ else if (r > ONIG_NORMAL) {\r
+ /* type == void: initial state */\r
+ OnigCodePoint c1, c2;\r
+ UChar* p;\r
+\r
+ r = onig_get_arg_by_callout_args(args, 1, &type, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ p = val.s.start;\r
+ c1 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
+ p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
+ if (p < val.s.end) {\r
+ c2 = ONIGENC_MBC_TO_CODE(reg->enc, p, val.s.end);\r
+ p += ONIGENC_MBC_ENC_LEN(reg->enc, p);\r
+ if (p != val.s.end) return ONIGERR_INVALID_CALLOUT_ARG;\r
+ }\r
+ else\r
+ c2 = 0;\r
+\r
+ switch (c1) {\r
+ case '=':\r
+ if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
+ op = OP_EQ;\r
+ break;\r
+ case '!':\r
+ if (c2 != '=') return ONIGERR_INVALID_CALLOUT_ARG;\r
+ op = OP_NE;\r
+ break;\r
+ case '<':\r
+ if (c2 == '=') op = OP_LE;\r
+ else if (c2 == 0) op = OP_LT;\r
+ else return ONIGERR_INVALID_CALLOUT_ARG;\r
+ break;\r
+ case '>':\r
+ if (c2 == '=') op = OP_GE;\r
+ else if (c2 == 0) op = OP_GT;\r
+ else return ONIGERR_INVALID_CALLOUT_ARG;\r
+ break;\r
+ default:\r
+ return ONIGERR_INVALID_CALLOUT_ARG;\r
+ break;\r
+ }\r
+ val.l = (long )op;\r
+ r = onig_set_callout_data_by_callout_args_self(args, slot, ONIG_TYPE_LONG, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+ }\r
+ else {\r
+ op = (enum OP_CMP )val.l;\r
+ }\r
+\r
+ switch (op) {\r
+ case OP_EQ: r = (lv == rv); break;\r
+ case OP_NE: r = (lv != rv); break;\r
+ case OP_LT: r = (lv < rv); break;\r
+ case OP_GT: r = (lv > rv); break;\r
+ case OP_LE: r = (lv <= rv); break;\r
+ case OP_GE: r = (lv >= rv); break;\r
+ }\r
+\r
+ return r == 0 ? ONIG_CALLOUT_FAIL : ONIG_CALLOUT_SUCCESS;\r
+}\r
+\r
+\r
+//#include <stdio.h>\r
+\r
+static FILE* OutFp;\r
+\r
+/* name start with "onig_" for macros. */\r
+static int\r
+onig_builtin_monitor(OnigCalloutArgs* args, void* user_data)\r
+{\r
+ int r;\r
+ int num;\r
+ size_t tag_len;\r
+ // const UChar* start;\r
+ // const UChar* right;\r
+ // const UChar* current;\r
+ // const UChar* string;\r
+ // const UChar* strend;\r
+ const UChar* tag_start;\r
+ const UChar* tag_end;\r
+ regex_t* reg;\r
+ OnigCalloutIn in;\r
+ OnigType type;\r
+ OnigValue val;\r
+ char buf[20];\r
+ // FILE* fp;\r
+\r
+ // fp = OutFp;\r
+\r
+ r = onig_get_arg_by_callout_args(args, 0, &type, &val);\r
+ if (r != ONIG_NORMAL) return r;\r
+\r
+ in = onig_get_callout_in_by_callout_args(args);\r
+ if (in == ONIG_CALLOUT_IN_PROGRESS) {\r
+ if (val.c == '<')\r
+ return ONIG_CALLOUT_SUCCESS;\r
+ }\r
+ else {\r
+ if (val.c != 'X' && val.c != '<')\r
+ return ONIG_CALLOUT_SUCCESS;\r
+ }\r
+\r
+ num = onig_get_callout_num_by_callout_args(args);\r
+ // start = onig_get_start_by_callout_args(args);\r
+ // right = onig_get_right_range_by_callout_args(args);\r
+ // current = onig_get_current_by_callout_args(args);\r
+ // string = onig_get_string_by_callout_args(args);\r
+ // strend = onig_get_string_end_by_callout_args(args);\r
+ reg = onig_get_regex_by_callout_args(args);\r
+ tag_start = onig_get_callout_tag_start(reg, num);\r
+ tag_end = onig_get_callout_tag_end(reg, num);\r
+\r
+ if (tag_start == 0)\r
+ sprintf_s(buf, sizeof(buf), "#%d", num);\r
+ else {\r
+ /* CAUTION: tag string is not terminated with NULL. */\r
+ int i;\r
+\r
+ tag_len = tag_end - tag_start;\r
+ if (tag_len >= sizeof(buf)) tag_len = sizeof(buf) - 1;\r
+ for (i = 0; i < tag_len; i++) buf[i] = tag_start[i];\r
+ buf[tag_len] = '\0';\r
+ }\r
+/*\r
+ fprintf(fp, "ONIG-MONITOR: %-4s %s at: %d [%d - %d] len: %d\n",\r
+ buf,\r
+ in == ONIG_CALLOUT_IN_PROGRESS ? "=>" : "<=",\r
+ (int )(current - string),\r
+ (int )(start - string),\r
+ (int )(right - string),\r
+ (int )(strend - string));\r
+ //fflush(fp);\r
+*/\r
+ return ONIG_CALLOUT_SUCCESS;\r
+}\r
+\r
+extern int\r
+onig_setup_builtin_monitors_by_ascii_encoded_name(void* fp /* FILE* */)\r
+{\r
+ int id;\r
+ char* name;\r
+ OnigEncoding enc;\r
+ unsigned int ts[4];\r
+ OnigValue opts[4];\r
+\r
+ if (IS_NOT_NULL(fp))\r
+ OutFp = (FILE* )fp;\r
+ else\r
+ OutFp = stdout;\r
+\r
+ enc = ONIG_ENCODING_ASCII;\r
+\r
+ name = "MON";\r
+ ts[0] = ONIG_TYPE_CHAR;\r
+ opts[0].c = '>';\r
+ BC_B_O(name, monitor, 1, ts, 1, opts);\r
+\r
+ return ONIG_NORMAL;\r
+}\r
+\r
+#endif /* USE_CALLOUT */\r