if (r != 0) return r;
r = add_mem_num(reg, node->dirs);
if (r != 0) return r;
- r = add_pointer(reg, pattern + node->code_start);
- if (r != 0) return r;
- r = add_pointer(reg, pattern + node->code_end);
- if (r != 0) return r;
+ if (node->code_start >= 0) {
+ r = add_pointer(reg, pattern + node->code_start);
+ if (r != 0) return r;
+ r = add_pointer(reg, pattern + node->code_end);
+ if (r != 0) return r;
+ }
+ else {
+ r = add_pointer(reg, 0);
+ if (r != 0) return r;
+ r = add_pointer(reg, 0);
+ if (r != 0) return r;
+ }
}
break;
GIMMICK_(*node)->dirs = dirs;
GIMMICK_(*node)->code_start = -1;
GIMMICK_(*node)->code_end = -1;
+ GIMMICK_(*node)->tag_start = -1;
+ GIMMICK_(*node)->tag_end = -1;
return ONIG_NORMAL;
}
UChar** src, UChar* end, ScanEnv* env);
#ifdef USE_CALLOUT
-/* (?{...}) (?{{...}}) */
+
+/* (?{...}[+-]) (?{{...}}[+-]) */
static int
parse_callout_of_code(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* env)
{
r = node_new_callout(np, ONIG_CALLOUT_OF_CODE, -1, dirs, env);
if (r != 0) return r;
- GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
- GIMMICK_(*np)->code_end = (int )(code_end - env->pattern);
+ if (code_start != code_end) {
+ GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
+ GIMMICK_(*np)->code_end = (int )(code_end - env->pattern);
+ }
*src = p;
return 0;
}
-/* (*NAME[+-]) (*NAME[+-]:...) */
+/* (*NAME[+-][TAG]) (*NAME[+-][TAG]{...}) */
static int
parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* env)
{
UChar* name_end;
UChar* code_start;
UChar* code_end;
+ UChar* tag_start;
+ UChar* tag_end;
OnigEncoding enc = env->enc;
UChar* p = *src;
if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
PFETCH_S(c);
- if (c == cterm || c == ':') break;
+ if (c == cterm || c == '[' || c == '{') break;
else
return ONIGERR_INVALID_CALLOUT_PATTERN;
}
- else if (c == cterm || c == ':') break;
+ else if (c == cterm || c == '[' || c == '{') break;
else if (c > 255)
return ONIGERR_INVALID_CALLOUT_NAME;
else {
}
}
- if (c == ':') {
- if (PEND) return ONIGERR_INVALID_CALLOUT_PATTERN;
+ if (c == '[') {
+ if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+ tag_start = p;
+ while (! PEND) {
+ tag_end = p;
+ PFETCH_S(c);
+ if (c == ']') break;
+ if (c > 255) return ONIGERR_INVALID_CALLOUT_TAG_NAME;
+ if (! ONIGENC_IS_CODE_ALNUM(enc, c) && c != '_')
+ return ONIGERR_INVALID_CALLOUT_TAG_NAME;
+ }
+ if (c != ']') return ONIGERR_END_PATTERN_IN_GROUP;
+
+ if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+ PFETCH_S(c);
+ }
+ else {
+ tag_start = tag_end = 0;
+ }
+
+ if (c == '{') {
+ if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+
code_start = p;
while (! PEND) {
code_end = p;
PFETCH_S(c);
- if (c == cterm) break;
+ if (c == '}') break;
}
- if (c != cterm) return ONIGERR_END_PATTERN_IN_GROUP;
+ if (c != '}') return ONIGERR_END_PATTERN_IN_GROUP;
+
+ if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+ PFETCH_S(c);
}
else {
code_start = code_end = 0;
r = node_new_callout(np, ONIG_CALLOUT_OF_NAME, id, dirs, env);
if (r != ONIG_NORMAL) return r;
- GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
- GIMMICK_(*np)->code_end = (int )(code_end - env->pattern);
+ if (code_start != code_end) {
+ GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
+ GIMMICK_(*np)->code_end = (int )(code_end - env->pattern);
+ }
+
+ if (tag_start != tag_end) {
+ GIMMICK_(*np)->tag_start = (int )(tag_start - env->pattern);
+ GIMMICK_(*np)->tag_end = (int )(tag_end - env->pattern);
+ }
*src = p;
return 0;