Thread View: gnu.utils.bug
1 messages
1 total messages
Started by David Boulware
Wed, 19 Aug 1992 19:42
regex bug?
Author: David Boulware
Date: Wed, 19 Aug 1992 19:42
Date: Wed, 19 Aug 1992 19:42
187 lines
6871 bytes
6871 bytes
Line 2393ff of regex.c from the textutils-1.1 distribution follow.
The variable 'enough_memory' is a pointer to a boolean quantity; however after
the first couple of uses, 'enough_memory' is used where '*enough_memory' appears
to be correct. These places are marked by /*HERE*/ notations.
If this observation is in error, please let me know.
static boolean
verify_and_adjust_endlines (op_list, group_forward_match_status,
bufp, enough_memory)
op_list_type op_list;
/* `duplicate' case needs this: which groups matched something;
set when went fowards through the pattern. */
bits_list_type group_forward_match_status;
struct re_pattern_buffer *bufp;
boolean *enough_memory;
{
int this_op_offset; /* Has to be type int because decrementing it. */
/* See comments for analogous variables used for '^' in regex_compile. */
bits_list_type level_match_status;
unsigned current_level = 0;
bits_list_type group_match_status;
bits_list_type group_active_status;
char *bend = bufp->buffer + bufp->used;
char *previous_p = NULL;
if (!(init_bits_list (&level_match_status)
&& init_bits_list (&group_match_status)
&& init_bits_list (&group_active_status)))
{
*enough_memory = false;
return true;
}
else
*enough_memory = true;
for (this_op_offset = op_list.avail - 1; this_op_offset >= 0;
this_op_offset--)
{
char *p = bufp->buffer + op_list.offsets[this_op_offset];
if (!enough_memory) /*HERE*/
break;
switch ((enum regexpcode) *p)
{
case endline:
case endline_in_repeat:
case endline_before_newline:
case repeated_endline_before_newline:
/* If the '$' must be at the pattern's end or else is
in a trailing position. */
if ((bufp->syntax & RE_ANCHORS_ONLY_AT_ENDS)
? p + 1 == bend
: ((bufp->syntax & RE_TIGHT_ALT)
? p + 3 == bend /* Would have two following no_ops. */
: (*p == endline_before_newline
|| *p == repeated_endline_before_newline
|| no_levels_match_anything (level_match_status))))
{
if ((enum regexpcode) *p == endline_in_repeat
|| (enum regexpcode) *p == repeated_endline_before_newline)
if (bufp->syntax & RE_REPEATED_ANCHORS_AWAY)
*p = no_op;
else
*p = endline;
/* If this is a trailing '$' in an empty alternative. */
if ((bufp->syntax & RE_NO_EMPTY_ALTS)
/* If there's an alternation op right before this `$'. */
&& ((this_op_offset > 0
&& *(bufp->buffer
+ op_list.offsets[this_op_offset - 1])
== jump_past_next_alt)
/* Or this `$' is the only thing in the first
alternative of more than one of them. */
|| ((this_op_offset == 0 /* It's first. */
/* Or it's right after an open-group op. */
|| (this_op_offset > 0
&& *(bufp->buffer
+ op_list.offsets[this_op_offset - 1])
== start_memory))
/* And it's right before an alternation op. */
&& previous_p != NULL
&& *previous_p == jump_past_next_alt)))
return false;
}
else if (bufp->syntax & RE_CONTEXT_INVALID_ANCHORS)
return false;
else if (!(bufp->syntax & RE_CONTEXT_INDEP_ANCHORS))
{
p[0] = (char)exactn;
p[1] = (char)1;
p[2] = '$';
}
break;
/* Yes, start and stop_memory are switched because we're going
backwards through the pattern! */
case stop_memory:
increase_level (¤t_level);
if (!make_group_active (&group_active_status, p[1]))
enough_memory = false; /*HERE*/
break;
case start_memory:
if (get_level_match_status (level_match_status, current_level))
if (!set_next_lower_level (&level_match_status, current_level))
enough_memory = false; /*HERE*/
else
{
decrease_level (¤t_level);
make_group_inactive (&group_active_status, p[1]);
}
break;
/* Hit an alternative. */
case jump_past_next_alt:
if (lower_levels_match_nothing (level_match_status, current_level))
clear_this_and_higher_levels (&level_match_status,current_level);
break;
/* These below mean was followed by a repetition operator. */
case no_op:
case maybe_pop_jump:
case no_pop_jump_n:
if (bufp->syntax & RE_REPEATED_ANCHORS_AWAY)
break;
case charset:
case charset_not:
case wordchar:
case notwordchar:
case exactn:
case anychar:
if (!set_this_level (&level_match_status, current_level)
|| !set_match_status_of_active_groups (group_active_status,
&group_match_status))
enough_memory = false;; /*HERE*/
break;
case duplicate:
/* Only set level_match_status if this back reference
refers to a nonempty group. */
if (get_group_match_status (group_forward_match_status, p[1]))
if (!set_this_level (&level_match_status, current_level))
enough_memory = false; /*HERE*/
break;
default:
printf ("Found an unknown operator %u in compiled pattern.\n", *p);
}
previous_p = p;
}
return true;
}
--
David G. Boulware
dgb@phys.washington.edu
Physics Dept, FM-15
University of Washington
Seattle, WA 98195
(206)-543-8591
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads