@ -401,8 +401,8 @@ typedef struct {
tre_ast_node_t * n ;
tre_ast_node_t * n ;
/* Position in the regexp pattern after a parse function returns. */
/* Position in the regexp pattern after a parse function returns. */
const char * s ;
const char * s ;
/* The first character of the regexp . */
/* The first character of the last subexpression parsed . */
const char * re ;
const char * start ;
/* Current submatch ID. */
/* Current submatch ID. */
int submatch_id ;
int submatch_id ;
/* Current position (number of literal). */
/* Current position (number of literal). */
@ -876,14 +876,14 @@ static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)
break ;
break ;
case ' ^ ' :
case ' ^ ' :
/* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
/* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
if ( ! ere & & s ! = ctx - > re )
if ( ! ere & & s ! = ctx - > start )
goto parse_literal ;
goto parse_literal ;
node = tre_ast_new_literal ( ctx - > mem , ASSERTION , ASSERT_AT_BOL , - 1 ) ;
node = tre_ast_new_literal ( ctx - > mem , ASSERTION , ASSERT_AT_BOL , - 1 ) ;
s + + ;
s + + ;
break ;
break ;
case ' $ ' :
case ' $ ' :
/* '$' is special everywhere in EREs, and in the end of the string in BREs . */
/* '$' is special everywhere in EREs, and at the end of a BRE subexpression . */
if ( ! ere & & s [ 1 ] )
if ( ! ere & & s [ 1 ] & & ( s [ 1 ] ! = ' \\ ' | | ( s [ 2 ] ! = ' ) ' & & s [ 2 ] ! = ' | ' ) ) )
goto parse_literal ;
goto parse_literal ;
node = tre_ast_new_literal ( ctx - > mem , ASSERTION , ASSERT_AT_EOL , - 1 ) ;
node = tre_ast_new_literal ( ctx - > mem , ASSERTION , ASSERT_AT_EOL , - 1 ) ;
s + + ;
s + + ;
@ -944,7 +944,7 @@ static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
{
{
tre_ast_node_t * nbranch = 0 , * nunion = 0 ;
tre_ast_node_t * nbranch = 0 , * nunion = 0 ;
int ere = ctx - > cflags & REG_EXTENDED ;
int ere = ctx - > cflags & REG_EXTENDED ;
const char * s = ctx - > re ;
const char * s = ctx - > start ;
int subid = 0 ;
int subid = 0 ;
int depth = 0 ;
int depth = 0 ;
reg_errcode_t err ;
reg_errcode_t err ;
@ -962,6 +962,7 @@ static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
s + + ;
s + + ;
depth + + ;
depth + + ;
nbranch = nunion = 0 ;
nbranch = nunion = 0 ;
ctx - > start = s ;
continue ;
continue ;
}
}
if ( ( ! ere & & * s = = ' \\ ' & & s [ 1 ] = = ' ) ' ) | |
if ( ( ! ere & & * s = = ' \\ ' & & s [ 1 ] = = ' ) ' ) | |
@ -994,8 +995,8 @@ static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
if ( * s = = ' \\ ' )
if ( * s = = ' \\ ' )
s + + ;
s + + ;
/* handle ^* at the start of a complete BRE. */
/* handle ^* at the start of a BRE. */
if ( ! ere & & s = = ctx - > re + 1 & & s [ - 1 ] = = ' ^ ' )
if ( ! ere & & s = = ctx - > start + 1 & & s [ - 1 ] = = ' ^ ' )
break ;
break ;
/* extension: multiple consecutive *+?{,} is unspecified,
/* extension: multiple consecutive *+?{,} is unspecified,
@ -1038,8 +1039,10 @@ static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
if ( c = = ' \\ ' & & s [ 1 ] = = ' | ' ) {
if ( c = = ' \\ ' & & s [ 1 ] = = ' | ' ) {
s + = 2 ;
s + = 2 ;
ctx - > start = s ;
} else if ( c = = ' | ' ) {
} else if ( c = = ' | ' ) {
s + + ;
s + + ;
ctx - > start = s ;
} else {
} else {
if ( c = = ' \\ ' ) {
if ( c = = ' \\ ' ) {
if ( ! depth ) return REG_EPAREN ;
if ( ! depth ) return REG_EPAREN ;
@ -2705,7 +2708,7 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
memset ( & parse_ctx , 0 , sizeof ( parse_ctx ) ) ;
memset ( & parse_ctx , 0 , sizeof ( parse_ctx ) ) ;
parse_ctx . mem = mem ;
parse_ctx . mem = mem ;
parse_ctx . stack = stack ;
parse_ctx . stack = stack ;
parse_ctx . re = regex ;
parse_ctx . start = regex ;
parse_ctx . cflags = cflags ;
parse_ctx . cflags = cflags ;
parse_ctx . max_backref = - 1 ;
parse_ctx . max_backref = - 1 ;
errcode = tre_parse ( & parse_ctx ) ;
errcode = tre_parse ( & parse_ctx ) ;