X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=regex.c;h=c9219c66c83624e8f2273ed11577ef22967a558b;hb=450b4b76f740833a6bbf188729e2c2acaf1b0699;hp=bdd84ef483e5873f737d16504f557179e65112fd;hpb=23fe33a2f02562d7a0ff072df874a0bcb10d649c;p=gnulib.git diff --git a/regex.c b/regex.c index bdd84ef48..c9219c66c 100644 --- a/regex.c +++ b/regex.c @@ -2,7 +2,7 @@ 0.12. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 1994-1998, 1999 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1512,8 +1512,8 @@ typedef struct \ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ \ - DEBUG_POP (&failure_id); \ - DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ + DEBUG_POP (&failure_id.integer); \ + DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id.integer); \ \ /* If the saved string location is NULL, it came from an \ on_failure_keep_string_jump opcode, and we want to throw away the \ @@ -2168,6 +2168,7 @@ regex_compile (pattern, size, syntax, bufp) /* 1 means zero (many) matches is allowed. */ char zero_times_ok = 0, many_times_ok = 0; + char greedy = 1; /* If there is a sequence of repetition chars, collapse it down to just one (the right one). We can't combine @@ -2176,8 +2177,14 @@ regex_compile (pattern, size, syntax, bufp) for (;;) { - zero_times_ok |= c != '+'; - many_times_ok |= c != '?'; + if (!(syntax & RE_ALL_GREEDY) + && c == '?' && (zero_times_ok || many_times_ok)) + greedy = 0; + else + { + zero_times_ok |= c != '+'; + many_times_ok |= c != '?'; + } if (p == pend) break; @@ -2218,6 +2225,8 @@ regex_compile (pattern, size, syntax, bufp) /* Now we know whether or not zero matches is allowed and also whether or not two or more matches is allowed. */ + if (greedy) + { if (many_times_ok) { /* More than one repetition is allowed, so put in at the end a backward relative jump from `b' to before the next @@ -2276,7 +2285,39 @@ regex_compile (pattern, size, syntax, bufp) INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); b += 3; } - } + + } + else /* not greedy */ + { /* I wish the greedy and non-greedy cases could be merged. */ + + if (many_times_ok) + { + /* The greedy multiple match looks like a repeat..until: + we only need a conditional jump at the end of the loop */ + GET_BUFFER_SPACE (3); + STORE_JUMP (on_failure_jump, b, laststart); + b += 3; + if (zero_times_ok) + { + /* The repeat...until naturally matches one or more. + To also match zero times, we need to first jump to + the end of the loop (its conditional jump). */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (jump, laststart, b); + b += 3; + } + } + else + { + /* non-greedy a?? */ + GET_BUFFER_SPACE (6); + INSERT_JUMP (jump, laststart, b + 3); + b += 3; + INSERT_JUMP (on_failure_jump, laststart, laststart + 6); + b += 3; + } + } + } break; @@ -3110,8 +3151,8 @@ regex_compile (pattern, size, syntax, bufp) #ifdef emacs if (! SINGLE_BYTE_CHAR_P (c)) { - unsigned char work[4], *str; - int i = CHAR_STRING (c, work, str); + unsigned char str[MAX_MULTIBYTE_LENGTH]; + int i = CHAR_STRING (c, str); int j; for (j = 0; j < i; j++) {