1991-03-28 16:28:29 +00:00
|
|
|
|
/* Extended regular expression matching and search library.
|
|
|
|
|
Copyright (C) 1985, 1989 Free Software Foundation, Inc.
|
|
|
|
|
|
1991-06-04 07:31:55 +00:00
|
|
|
|
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
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
1995-08-02 03:41:12 +00:00
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
|
|
|
|
/* To test, compile with -Dtest.
|
|
|
|
|
This Dtestable feature turns this into a self-contained program
|
|
|
|
|
which reads a pattern, describes how it compiles,
|
|
|
|
|
then reads a string and searches for it. */
|
|
|
|
|
|
|
|
|
|
#ifdef emacs
|
|
|
|
|
|
|
|
|
|
/* The `emacs' switch turns on certain special matching commands
|
|
|
|
|
that make sense only in emacs. */
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "lisp.h"
|
|
|
|
|
#include "buffer.h"
|
|
|
|
|
#include "syntax.h"
|
|
|
|
|
|
|
|
|
|
#else /* not emacs */
|
|
|
|
|
|
* README: Remove note about gcc warnings on alpha, these should be
gone now.
* c-exp.y, ch-exp.y, core.c, corelow.c, eval.c, fork-child.c,
m2-exp.y, minsyms.c, nlmread.c, parse.c, putenv.c, regex.c
remote-utils.c, stabsread.c: Include <string.h>.
* regex.c: Include "defs.h", change re_comp argument to const char *.
* infptrace.c (fetch_register, store_inferior_registers): Change
regaddr to type CORE_ADDR.
* config/alpha/alpha-nw.mt, config/alpha/alpha-osf1.mt (MT_CFLAGS):
Remove, no longer necessary now that we use bfd_vma for a CORE_ADDR.
1994-02-08 09:01:03 +00:00
|
|
|
|
#include "defs.h"
|
* configure.in: Check for working mmap, ansi headers, string.h,
strings.h, and memory.h.
* configure: Regenerated.
* gdb_stat.h: New file, "portable" <sys/stat.h>.
* gdb_string.h: New file, "portable" <string.h>.
* altos-xdep.c, arm-tdep.c, arm-xdep.c, convex-tdep.c,
convex-xdep.c, coredep.c, cxux-nat.c, dbxread.c, exec.c,
gould-xdep.c, hppa-tdep.c, i386aix-nat.c, i386b-nat.c,
i386mach-nat.c, i386v-nat.c, infptrace.c, m88k-nat.c, main.c,
mdebugread.c, objfiles.c, os9kread.c, procfs.c, pyr-xdep.c,
rs6000-nat.c, source.c, standalone.c, stuff.c, sun386-nat.c,
symfile.c, symm-nat.c, symm-tdep.c, symtab.c, top.c, ultra3-nat.c,
ultra3-xdep.c, umax-xdep.c, xcoffread.c: Include "gdb_stat.h"
instead of <sys/stat.h>.
* alpha-tdep.c, breakpoint.c, buildsym.c, c-typeprint.c,
ch-typeprint.c, coffread.c, command.c, core-sol2.c, core-svr4.c,
core.c, corelow.c, cp-valprint.c, dbxread.c, dcache.c, demangle.c,
dpx2-nat.c, dstread.c, dwarfread.c, elfread.c, environ.c, eval.c,
exec.c, f-lang.c, f-typeprint.c, f-valprint.c, findvar.c,
fork-child.c, gdbtypes.c, hpread.c, i386-tdep.c, infcmd.c,
inflow.c, infptrace.c, infrun.c, irix5-nat.c, language.c,
m2-typeprint.c, main.c, mdebugread.c, minsyms.c, mipsread.c,
monitor.c, nlmread.c, objfiles.c, os9kread.c, osfsolib.c, parse.c,
printcmd.c, procfs.c, regex.c, remote-adapt.c, remote-arc.c,
remote-array.c, remote-bug.c, remote-e7000.c, remote-eb.c,
remote-es.c, remote-hms.c, remote-mm.c, remote-os9k.c,
remote-pa.c, remote-sim.c, remote-st.c, remote-udi.c,
remote-utils.c, remote-vx.c, remote-vx29k.c, remote-vx68.c,
remote-vx960.c, remote-vxmips.c, remote-vxsparc.c, remote.c,
solib.c, somread.c, source.c, stabsread.c, stack.c, symfile.c,
symmisc.c, symtab.c, target.c, top.c, typeprint.c, utils.c,
valarith.c, valops.c, valprint.c, values.c, xcoffread.c: Include
"gdb_string.h" instead of <string.h>.
* gdbtk.c: Likewise.
* config/xm-sysv4.h, i386/xm-ptx.h, m68k/xm-sun3os4.h,
sparc/xm-sun4os4.h (HAVE_MMAP): Removed.
* config/xm-lynx.h, config/i386/xm-ptx.h,
config/m68k/nm-apollo68b.h, config/m68k/xm-hp300hpux.h,
config/mips/xm-irix3.h, config/mips/xm-mips.h,
config/mips/xm-news-mips.h, config/mips/xm-riscos.h,
config/pa/hppah.h, config/rs6000/xm-rs6000.h,
config/sparc/xm-sun4os4.h, config/sparc/xm-sun4sol2.h,
config/vax/xm-vaxbsd.h, config/vax/xm-vaxult.h,
config/vax/xm-vaxult2.h (MEM_FNS_DECLARED): Removed.
* config/mips/xm-irix3.h, config/mips/xm-mips.h,
config/pa/xm-hppah.h (memcpy, memset): Removed declarations.
1995-08-01 20:14:27 +00:00
|
|
|
|
#include "gdb_string.h"
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Define the syntax stuff, so we can do the \<...\> things.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef Sword /* must be non-zero in some of the tests below... */
|
|
|
|
|
#define Sword 1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define SYNTAX(c) re_syntax_table[c]
|
|
|
|
|
|
|
|
|
|
#ifdef SYNTAX_TABLE
|
|
|
|
|
|
|
|
|
|
char *re_syntax_table;
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
static char re_syntax_table[256];
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_syntax_once ()
|
|
|
|
|
{
|
|
|
|
|
register int c;
|
|
|
|
|
static int done = 0;
|
|
|
|
|
|
|
|
|
|
if (done)
|
|
|
|
|
return;
|
|
|
|
|
|
1993-09-01 21:56:42 +00:00
|
|
|
|
memset (re_syntax_table, '\0', sizeof re_syntax_table);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
|
|
|
|
for (c = 'a'; c <= 'z'; c++)
|
|
|
|
|
re_syntax_table[c] = Sword;
|
|
|
|
|
|
|
|
|
|
for (c = 'A'; c <= 'Z'; c++)
|
|
|
|
|
re_syntax_table[c] = Sword;
|
|
|
|
|
|
|
|
|
|
for (c = '0'; c <= '9'; c++)
|
|
|
|
|
re_syntax_table[c] = Sword;
|
|
|
|
|
|
|
|
|
|
done = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* SYNTAX_TABLE */
|
|
|
|
|
#endif /* not emacs */
|
|
|
|
|
|
|
|
|
|
#include "regex.h"
|
|
|
|
|
|
|
|
|
|
/* Number of failure points to allocate space for initially,
|
|
|
|
|
when matching. If this number is exceeded, more space is allocated,
|
|
|
|
|
so it is not a hard limit. */
|
|
|
|
|
|
|
|
|
|
#ifndef NFAILURES
|
|
|
|
|
#define NFAILURES 80
|
|
|
|
|
#endif /* NFAILURES */
|
|
|
|
|
|
|
|
|
|
/* width of a byte in bits */
|
|
|
|
|
|
|
|
|
|
#define BYTEWIDTH 8
|
|
|
|
|
|
1994-08-07 13:33:45 +00:00
|
|
|
|
/* We remove any previous definition of `SIGN_EXTEND_CHAR',
|
|
|
|
|
since ours (we hope) works properly with all combinations of
|
|
|
|
|
machines, compilers, `char' and `unsigned char' argument types.
|
|
|
|
|
(Per Bothner suggested the basic approach.) */
|
|
|
|
|
#undef SIGN_EXTEND_CHAR
|
|
|
|
|
#if __STDC__
|
|
|
|
|
#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
|
|
|
|
|
#else /* not __STDC__ */
|
|
|
|
|
/* As in Harbison and Steele. */
|
|
|
|
|
#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
|
1991-03-28 16:28:29 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static int obscure_syntax = 0;
|
|
|
|
|
|
|
|
|
|
/* Specify the precise syntax of regexp for compilation.
|
|
|
|
|
This provides for compatibility for various utilities
|
|
|
|
|
which historically have different, incompatible syntaxes.
|
|
|
|
|
|
|
|
|
|
The argument SYNTAX is a bit-mask containing the two bits
|
|
|
|
|
RE_NO_BK_PARENS and RE_NO_BK_VBAR. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
re_set_syntax (syntax)
|
* dbxread.c, i386-pinsn.c, i386-tdep.c, regex.c, solib.c, symmisc.c,
symtab.h, tm-i386v4.h, valprint.c, values.c: Lint.
* breakpoint.c, c-exp.y, coffread.c, command.c, environ.c, eval.c,
findvar.c, infcmd.c, infptrace.c, infrun.c, m2-exp.y, parse.c,
putenv.c, solib.c, sparc-xdep.c, symtab.c, tm-i386v.h, tm-sparc.h,
utils.c, valarith.c, valops.c, valprint.c, values.c:
Replace bcopy() use with memcpy(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
* breakpoint.c, buildsym.c, coffread.c, dbxread.c, i386-tdep.c,
ieee-float.c, infcmd.c, sparc-tdep.c, stack.c, symtab.c, symtab.h,
target.c, values.c:
Replace bzero() use with memset(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
* i386-tdep.c, main.c, valprint.c:
Replace bcmp() use with memcmp(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
1992-06-29 23:34:38 +00:00
|
|
|
|
int syntax;
|
1991-03-28 16:28:29 +00:00
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = obscure_syntax;
|
|
|
|
|
obscure_syntax = syntax;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* re_compile_pattern takes a regular-expression string
|
|
|
|
|
and converts it into a buffer full of byte commands for matching.
|
|
|
|
|
|
|
|
|
|
PATTERN is the address of the pattern string
|
|
|
|
|
SIZE is the length of it.
|
|
|
|
|
BUFP is a struct re_pattern_buffer * which points to the info
|
|
|
|
|
on where to store the byte commands.
|
|
|
|
|
This structure contains a char * which points to the
|
|
|
|
|
actual space, which should have been obtained with malloc.
|
|
|
|
|
re_compile_pattern may use realloc to grow the buffer space.
|
|
|
|
|
|
|
|
|
|
The number of bytes of commands can be found out by looking in
|
|
|
|
|
the struct re_pattern_buffer that bufp pointed to,
|
|
|
|
|
after re_compile_pattern returns.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define PATPUSH(ch) (*b++ = (char) (ch))
|
|
|
|
|
|
|
|
|
|
#define PATFETCH(c) \
|
|
|
|
|
{if (p == pend) goto end_of_pattern; \
|
|
|
|
|
c = * (unsigned char *) p++; \
|
|
|
|
|
if (translate) c = translate[c]; }
|
|
|
|
|
|
|
|
|
|
#define PATFETCH_RAW(c) \
|
|
|
|
|
{if (p == pend) goto end_of_pattern; \
|
|
|
|
|
c = * (unsigned char *) p++; }
|
|
|
|
|
|
|
|
|
|
#define PATUNFETCH p--
|
|
|
|
|
|
1994-03-18 18:34:36 +00:00
|
|
|
|
/* This is not an arbitrary limit: the arguments which represent offsets
|
|
|
|
|
into the pattern are two bytes long. So if 2^16 bytes turns out to
|
|
|
|
|
be too small, many things would have to change. */
|
|
|
|
|
#define MAX_BUF_SIZE (1 << 16)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Extend the buffer by twice its current size via realloc and
|
|
|
|
|
reset the pointers that pointed into the old block to point to the
|
|
|
|
|
correct places in the new one. If extending the buffer results in it
|
|
|
|
|
being larger than MAX_BUF_SIZE, then flag memory exhausted. */
|
|
|
|
|
#define EXTEND_BUFFER \
|
|
|
|
|
do { \
|
|
|
|
|
char *old_buffer = bufp->buffer; \
|
|
|
|
|
if (bufp->allocated == MAX_BUF_SIZE) \
|
|
|
|
|
goto too_big; \
|
|
|
|
|
bufp->allocated <<= 1; \
|
|
|
|
|
if (bufp->allocated > MAX_BUF_SIZE) \
|
|
|
|
|
bufp->allocated = MAX_BUF_SIZE; \
|
|
|
|
|
bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated);\
|
|
|
|
|
if (bufp->buffer == NULL) \
|
|
|
|
|
goto memory_exhausted; \
|
|
|
|
|
/* If the buffer moved, move all the pointers into it. */ \
|
|
|
|
|
if (old_buffer != bufp->buffer) \
|
|
|
|
|
{ \
|
|
|
|
|
b = (b - old_buffer) + bufp->buffer; \
|
|
|
|
|
begalt = (begalt - old_buffer) + bufp->buffer; \
|
|
|
|
|
if (fixup_jump) \
|
|
|
|
|
fixup_jump = (fixup_jump - old_buffer) + bufp->buffer;\
|
|
|
|
|
if (laststart) \
|
|
|
|
|
laststart = (laststart - old_buffer) + bufp->buffer; \
|
|
|
|
|
if (pending_exact) \
|
|
|
|
|
pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
|
|
|
|
|
} \
|
|
|
|
|
} while (0)
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
1992-06-25 19:10:49 +00:00
|
|
|
|
static void store_jump (), insert_jump ();
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
re_compile_pattern (pattern, size, bufp)
|
|
|
|
|
char *pattern;
|
|
|
|
|
int size;
|
|
|
|
|
struct re_pattern_buffer *bufp;
|
|
|
|
|
{
|
|
|
|
|
register char *b = bufp->buffer;
|
|
|
|
|
register char *p = pattern;
|
|
|
|
|
char *pend = pattern + size;
|
|
|
|
|
register unsigned c, c1;
|
|
|
|
|
char *p1;
|
|
|
|
|
unsigned char *translate = (unsigned char *) bufp->translate;
|
|
|
|
|
|
|
|
|
|
/* address of the count-byte of the most recently inserted "exactn" command.
|
|
|
|
|
This makes it possible to tell whether a new exact-match character
|
|
|
|
|
can be added to that command or requires a new "exactn" command. */
|
|
|
|
|
|
|
|
|
|
char *pending_exact = 0;
|
|
|
|
|
|
|
|
|
|
/* address of the place where a forward-jump should go
|
|
|
|
|
to the end of the containing expression.
|
|
|
|
|
Each alternative of an "or", except the last, ends with a forward-jump
|
|
|
|
|
of this sort. */
|
|
|
|
|
|
|
|
|
|
char *fixup_jump = 0;
|
|
|
|
|
|
|
|
|
|
/* address of start of the most recently finished expression.
|
|
|
|
|
This tells postfix * where to find the start of its operand. */
|
|
|
|
|
|
|
|
|
|
char *laststart = 0;
|
|
|
|
|
|
|
|
|
|
/* In processing a repeat, 1 means zero matches is allowed */
|
|
|
|
|
|
|
|
|
|
char zero_times_ok;
|
|
|
|
|
|
|
|
|
|
/* In processing a repeat, 1 means many matches is allowed */
|
|
|
|
|
|
|
|
|
|
char many_times_ok;
|
|
|
|
|
|
|
|
|
|
/* address of beginning of regexp, or inside of last \( */
|
|
|
|
|
|
|
|
|
|
char *begalt = b;
|
|
|
|
|
|
|
|
|
|
/* Stack of information saved by \( and restored by \).
|
|
|
|
|
Four stack elements are pushed by each \(:
|
|
|
|
|
First, the value of b.
|
|
|
|
|
Second, the value of fixup_jump.
|
|
|
|
|
Third, the value of regnum.
|
|
|
|
|
Fourth, the value of begalt. */
|
|
|
|
|
|
|
|
|
|
int stackb[40];
|
|
|
|
|
int *stackp = stackb;
|
|
|
|
|
int *stacke = stackb + 40;
|
|
|
|
|
int *stackt;
|
|
|
|
|
|
|
|
|
|
/* Counts \('s as they are encountered. Remembered for the matching \),
|
|
|
|
|
where it becomes the "register number" to put in the stop_memory command */
|
|
|
|
|
|
|
|
|
|
int regnum = 1;
|
|
|
|
|
|
|
|
|
|
bufp->fastmap_accurate = 0;
|
|
|
|
|
|
|
|
|
|
#ifndef emacs
|
|
|
|
|
#ifndef SYNTAX_TABLE
|
|
|
|
|
/*
|
|
|
|
|
* Initialize the syntax table.
|
|
|
|
|
*/
|
|
|
|
|
init_syntax_once();
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (bufp->allocated == 0)
|
|
|
|
|
{
|
|
|
|
|
bufp->allocated = 28;
|
|
|
|
|
if (bufp->buffer)
|
|
|
|
|
/* EXTEND_BUFFER loses when bufp->allocated is 0 */
|
|
|
|
|
bufp->buffer = (char *) realloc (bufp->buffer, 28);
|
|
|
|
|
else
|
|
|
|
|
/* Caller did not allocate a buffer. Do it for him */
|
|
|
|
|
bufp->buffer = (char *) malloc (28);
|
|
|
|
|
if (!bufp->buffer) goto memory_exhausted;
|
|
|
|
|
begalt = b = bufp->buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (p != pend)
|
|
|
|
|
{
|
|
|
|
|
if (b - bufp->buffer > bufp->allocated - 10)
|
|
|
|
|
/* Note that EXTEND_BUFFER clobbers c */
|
|
|
|
|
EXTEND_BUFFER;
|
|
|
|
|
|
|
|
|
|
PATFETCH (c);
|
|
|
|
|
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case '$':
|
|
|
|
|
if (obscure_syntax & RE_TIGHT_VBAR)
|
|
|
|
|
{
|
|
|
|
|
if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
|
|
|
|
|
goto normal_char;
|
|
|
|
|
/* Make operand of last vbar end before this `$'. */
|
|
|
|
|
if (fixup_jump)
|
|
|
|
|
store_jump (fixup_jump, jump, b);
|
|
|
|
|
fixup_jump = 0;
|
|
|
|
|
PATPUSH (endline);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* $ means succeed if at end of line, but only in special contexts.
|
|
|
|
|
If randomly in the middle of a pattern, it is a normal character. */
|
|
|
|
|
if (p == pend || *p == '\n'
|
|
|
|
|
|| (obscure_syntax & RE_CONTEXT_INDEP_OPS)
|
|
|
|
|
|| (obscure_syntax & RE_NO_BK_PARENS
|
|
|
|
|
? *p == ')'
|
|
|
|
|
: *p == '\\' && p[1] == ')')
|
|
|
|
|
|| (obscure_syntax & RE_NO_BK_VBAR
|
|
|
|
|
? *p == '|'
|
|
|
|
|
: *p == '\\' && p[1] == '|'))
|
|
|
|
|
{
|
|
|
|
|
PATPUSH (endline);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
goto normal_char;
|
|
|
|
|
|
|
|
|
|
case '^':
|
|
|
|
|
/* ^ means succeed if at beg of line, but only if no preceding pattern. */
|
|
|
|
|
|
|
|
|
|
if (laststart && p[-2] != '\n'
|
|
|
|
|
&& ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
if (obscure_syntax & RE_TIGHT_VBAR)
|
|
|
|
|
{
|
|
|
|
|
if (p != pattern + 1
|
|
|
|
|
&& ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
PATPUSH (begline);
|
|
|
|
|
begalt = b;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
PATPUSH (begline);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '+':
|
|
|
|
|
case '?':
|
|
|
|
|
if (obscure_syntax & RE_BK_PLUS_QM)
|
|
|
|
|
goto normal_char;
|
|
|
|
|
handle_plus:
|
|
|
|
|
case '*':
|
|
|
|
|
/* If there is no previous pattern, char not special. */
|
|
|
|
|
if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
/* If there is a sequence of repetition chars,
|
|
|
|
|
collapse it down to equivalent to just one. */
|
|
|
|
|
zero_times_ok = 0;
|
|
|
|
|
many_times_ok = 0;
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
zero_times_ok |= c != '+';
|
|
|
|
|
many_times_ok |= c != '?';
|
|
|
|
|
if (p == pend)
|
|
|
|
|
break;
|
|
|
|
|
PATFETCH (c);
|
|
|
|
|
if (c == '*')
|
|
|
|
|
;
|
|
|
|
|
else if (!(obscure_syntax & RE_BK_PLUS_QM)
|
|
|
|
|
&& (c == '+' || c == '?'))
|
|
|
|
|
;
|
|
|
|
|
else if ((obscure_syntax & RE_BK_PLUS_QM)
|
|
|
|
|
&& c == '\\')
|
|
|
|
|
{
|
|
|
|
|
int c1;
|
|
|
|
|
PATFETCH (c1);
|
|
|
|
|
if (!(c1 == '+' || c1 == '?'))
|
|
|
|
|
{
|
|
|
|
|
PATUNFETCH;
|
|
|
|
|
PATUNFETCH;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
c = c1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PATUNFETCH;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Star, etc. applied to an empty pattern is equivalent
|
|
|
|
|
to an empty pattern. */
|
|
|
|
|
if (!laststart)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Now we know whether 0 matches is allowed,
|
|
|
|
|
and whether 2 or more matches is allowed. */
|
|
|
|
|
if (many_times_ok)
|
|
|
|
|
{
|
|
|
|
|
/* If more than one repetition is allowed,
|
|
|
|
|
put in a backward jump at the end. */
|
|
|
|
|
store_jump (b, maybe_finalize_jump, laststart - 3);
|
|
|
|
|
b += 3;
|
|
|
|
|
}
|
|
|
|
|
insert_jump (on_failure_jump, laststart, b + 3, b);
|
|
|
|
|
pending_exact = 0;
|
|
|
|
|
b += 3;
|
|
|
|
|
if (!zero_times_ok)
|
|
|
|
|
{
|
|
|
|
|
/* At least one repetition required: insert before the loop
|
|
|
|
|
a skip over the initial on-failure-jump instruction */
|
|
|
|
|
insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
|
|
|
|
|
b += 3;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '.':
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (anychar);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '[':
|
|
|
|
|
while (b - bufp->buffer
|
|
|
|
|
> bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
|
|
|
|
|
/* Note that EXTEND_BUFFER clobbers c */
|
|
|
|
|
EXTEND_BUFFER;
|
|
|
|
|
|
|
|
|
|
laststart = b;
|
|
|
|
|
if (*p == '^')
|
|
|
|
|
PATPUSH (charset_not), p++;
|
|
|
|
|
else
|
|
|
|
|
PATPUSH (charset);
|
|
|
|
|
p1 = p;
|
|
|
|
|
|
|
|
|
|
PATPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
|
|
|
|
|
/* Clear the whole map */
|
1993-09-01 21:56:42 +00:00
|
|
|
|
memset (b, '\0', (1 << BYTEWIDTH) / BYTEWIDTH);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
/* Read in characters and ranges, setting map bits */
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
PATFETCH (c);
|
|
|
|
|
if (c == ']' && p != p1 + 1) break;
|
|
|
|
|
if (*p == '-' && p[1] != ']')
|
|
|
|
|
{
|
|
|
|
|
PATFETCH (c1);
|
|
|
|
|
PATFETCH (c1);
|
|
|
|
|
while (c <= c1)
|
|
|
|
|
b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH), c++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Discard any bitmap bytes that are all 0 at the end of the map.
|
|
|
|
|
Decrement the map-length byte too. */
|
|
|
|
|
while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
|
|
|
|
|
b[-1]--;
|
|
|
|
|
b += b[-1];
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '(':
|
|
|
|
|
if (! (obscure_syntax & RE_NO_BK_PARENS))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
else
|
|
|
|
|
goto handle_open;
|
|
|
|
|
|
|
|
|
|
case ')':
|
|
|
|
|
if (! (obscure_syntax & RE_NO_BK_PARENS))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
else
|
|
|
|
|
goto handle_close;
|
|
|
|
|
|
|
|
|
|
case '\n':
|
|
|
|
|
if (! (obscure_syntax & RE_NEWLINE_OR))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
else
|
|
|
|
|
goto handle_bar;
|
|
|
|
|
|
|
|
|
|
case '|':
|
|
|
|
|
if (! (obscure_syntax & RE_NO_BK_VBAR))
|
|
|
|
|
goto normal_char;
|
|
|
|
|
else
|
|
|
|
|
goto handle_bar;
|
|
|
|
|
|
|
|
|
|
case '\\':
|
|
|
|
|
if (p == pend) goto invalid_pattern;
|
|
|
|
|
PATFETCH_RAW (c);
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case '(':
|
|
|
|
|
if (obscure_syntax & RE_NO_BK_PARENS)
|
|
|
|
|
goto normal_backsl;
|
|
|
|
|
handle_open:
|
|
|
|
|
if (stackp == stacke) goto nesting_too_deep;
|
|
|
|
|
if (regnum < RE_NREGS)
|
|
|
|
|
{
|
|
|
|
|
PATPUSH (start_memory);
|
|
|
|
|
PATPUSH (regnum);
|
|
|
|
|
}
|
|
|
|
|
*stackp++ = b - bufp->buffer;
|
|
|
|
|
*stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
|
|
|
|
|
*stackp++ = regnum++;
|
|
|
|
|
*stackp++ = begalt - bufp->buffer;
|
|
|
|
|
fixup_jump = 0;
|
|
|
|
|
laststart = 0;
|
|
|
|
|
begalt = b;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ')':
|
|
|
|
|
if (obscure_syntax & RE_NO_BK_PARENS)
|
|
|
|
|
goto normal_backsl;
|
|
|
|
|
handle_close:
|
|
|
|
|
if (stackp == stackb) goto unmatched_close;
|
|
|
|
|
begalt = *--stackp + bufp->buffer;
|
|
|
|
|
if (fixup_jump)
|
|
|
|
|
store_jump (fixup_jump, jump, b);
|
|
|
|
|
if (stackp[-1] < RE_NREGS)
|
|
|
|
|
{
|
|
|
|
|
PATPUSH (stop_memory);
|
|
|
|
|
PATPUSH (stackp[-1]);
|
|
|
|
|
}
|
|
|
|
|
stackp -= 2;
|
|
|
|
|
fixup_jump = 0;
|
|
|
|
|
if (*stackp)
|
|
|
|
|
fixup_jump = *stackp + bufp->buffer - 1;
|
|
|
|
|
laststart = *--stackp + bufp->buffer;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '|':
|
|
|
|
|
if (obscure_syntax & RE_NO_BK_VBAR)
|
|
|
|
|
goto normal_backsl;
|
|
|
|
|
handle_bar:
|
|
|
|
|
insert_jump (on_failure_jump, begalt, b + 6, b);
|
|
|
|
|
pending_exact = 0;
|
|
|
|
|
b += 3;
|
|
|
|
|
if (fixup_jump)
|
|
|
|
|
store_jump (fixup_jump, jump, b);
|
|
|
|
|
fixup_jump = b;
|
|
|
|
|
b += 3;
|
|
|
|
|
laststart = 0;
|
|
|
|
|
begalt = b;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#ifdef emacs
|
|
|
|
|
case '=':
|
|
|
|
|
PATPUSH (at_dot);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 's':
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (syntaxspec);
|
|
|
|
|
PATFETCH (c);
|
|
|
|
|
PATPUSH (syntax_spec_code[c]);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'S':
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (notsyntaxspec);
|
|
|
|
|
PATFETCH (c);
|
|
|
|
|
PATPUSH (syntax_spec_code[c]);
|
|
|
|
|
break;
|
|
|
|
|
#endif /* emacs */
|
|
|
|
|
|
|
|
|
|
case 'w':
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (wordchar);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'W':
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (notwordchar);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '<':
|
|
|
|
|
PATPUSH (wordbeg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '>':
|
|
|
|
|
PATPUSH (wordend);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'b':
|
|
|
|
|
PATPUSH (wordbound);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'B':
|
|
|
|
|
PATPUSH (notwordbound);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '`':
|
|
|
|
|
PATPUSH (begbuf);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '\'':
|
|
|
|
|
PATPUSH (endbuf);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '1':
|
|
|
|
|
case '2':
|
|
|
|
|
case '3':
|
|
|
|
|
case '4':
|
|
|
|
|
case '5':
|
|
|
|
|
case '6':
|
|
|
|
|
case '7':
|
|
|
|
|
case '8':
|
|
|
|
|
case '9':
|
|
|
|
|
c1 = c - '0';
|
|
|
|
|
if (c1 >= regnum)
|
|
|
|
|
goto normal_char;
|
|
|
|
|
for (stackt = stackp - 2; stackt > stackb; stackt -= 4)
|
|
|
|
|
if (*stackt == c1)
|
|
|
|
|
goto normal_char;
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (duplicate);
|
|
|
|
|
PATPUSH (c1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '+':
|
|
|
|
|
case '?':
|
|
|
|
|
if (obscure_syntax & RE_BK_PLUS_QM)
|
|
|
|
|
goto handle_plus;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
normal_backsl:
|
|
|
|
|
/* You might think it would be useful for \ to mean
|
|
|
|
|
not to translate; but if we don't translate it
|
|
|
|
|
it will never match anything. */
|
|
|
|
|
if (translate) c = translate[c];
|
|
|
|
|
goto normal_char;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
normal_char:
|
|
|
|
|
if (!pending_exact || pending_exact + *pending_exact + 1 != b
|
|
|
|
|
|| *pending_exact == 0177 || *p == '*' || *p == '^'
|
|
|
|
|
|| ((obscure_syntax & RE_BK_PLUS_QM)
|
|
|
|
|
? *p == '\\' && (p[1] == '+' || p[1] == '?')
|
|
|
|
|
: (*p == '+' || *p == '?')))
|
|
|
|
|
{
|
|
|
|
|
laststart = b;
|
|
|
|
|
PATPUSH (exactn);
|
|
|
|
|
pending_exact = b;
|
|
|
|
|
PATPUSH (0);
|
|
|
|
|
}
|
|
|
|
|
PATPUSH (c);
|
|
|
|
|
(*pending_exact)++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fixup_jump)
|
|
|
|
|
store_jump (fixup_jump, jump, b);
|
|
|
|
|
|
|
|
|
|
if (stackp != stackb) goto unmatched_open;
|
|
|
|
|
|
|
|
|
|
bufp->used = b - bufp->buffer;
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
invalid_pattern:
|
|
|
|
|
return "Invalid regular expression";
|
|
|
|
|
|
|
|
|
|
unmatched_open:
|
|
|
|
|
return "Unmatched \\(";
|
|
|
|
|
|
|
|
|
|
unmatched_close:
|
|
|
|
|
return "Unmatched \\)";
|
|
|
|
|
|
|
|
|
|
end_of_pattern:
|
|
|
|
|
return "Premature end of regular expression";
|
|
|
|
|
|
|
|
|
|
nesting_too_deep:
|
|
|
|
|
return "Nesting too deep";
|
|
|
|
|
|
|
|
|
|
too_big:
|
|
|
|
|
return "Regular expression too big";
|
|
|
|
|
|
|
|
|
|
memory_exhausted:
|
|
|
|
|
return "Memory exhausted";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Store where `from' points a jump operation to jump to where `to' points.
|
|
|
|
|
`opcode' is the opcode to store. */
|
|
|
|
|
|
1992-06-25 19:10:49 +00:00
|
|
|
|
static void
|
1991-03-28 16:28:29 +00:00
|
|
|
|
store_jump (from, opcode, to)
|
|
|
|
|
char *from, *to;
|
|
|
|
|
char opcode;
|
|
|
|
|
{
|
|
|
|
|
from[0] = opcode;
|
|
|
|
|
from[1] = (to - (from + 3)) & 0377;
|
|
|
|
|
from[2] = (to - (from + 3)) >> 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Open up space at char FROM, and insert there a jump to TO.
|
|
|
|
|
CURRENT_END gives te end of the storage no in use,
|
|
|
|
|
so we know how much data to copy up.
|
|
|
|
|
OP is the opcode of the jump to insert.
|
|
|
|
|
|
|
|
|
|
If you call this function, you must zero out pending_exact. */
|
|
|
|
|
|
1992-06-25 19:10:49 +00:00
|
|
|
|
static void
|
1991-03-28 16:28:29 +00:00
|
|
|
|
insert_jump (op, from, to, current_end)
|
|
|
|
|
char op;
|
|
|
|
|
char *from, *to, *current_end;
|
|
|
|
|
{
|
|
|
|
|
register char *pto = current_end + 3;
|
|
|
|
|
register char *pfrom = current_end;
|
|
|
|
|
while (pfrom != from)
|
|
|
|
|
*--pto = *--pfrom;
|
|
|
|
|
store_jump (from, op, to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Given a pattern, compute a fastmap from it.
|
|
|
|
|
The fastmap records which of the (1 << BYTEWIDTH) possible characters
|
|
|
|
|
can start a string that matches the pattern.
|
|
|
|
|
This fastmap is used by re_search to skip quickly over totally implausible text.
|
|
|
|
|
|
|
|
|
|
The caller must supply the address of a (1 << BYTEWIDTH)-byte data area
|
|
|
|
|
as bufp->fastmap.
|
|
|
|
|
The other components of bufp describe the pattern to be used. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
re_compile_fastmap (bufp)
|
|
|
|
|
struct re_pattern_buffer *bufp;
|
|
|
|
|
{
|
|
|
|
|
unsigned char *pattern = (unsigned char *) bufp->buffer;
|
|
|
|
|
int size = bufp->used;
|
|
|
|
|
register char *fastmap = bufp->fastmap;
|
|
|
|
|
register unsigned char *p = pattern;
|
|
|
|
|
register unsigned char *pend = pattern + size;
|
* dbxread.c, i386-pinsn.c, i386-tdep.c, regex.c, solib.c, symmisc.c,
symtab.h, tm-i386v4.h, valprint.c, values.c: Lint.
* breakpoint.c, c-exp.y, coffread.c, command.c, environ.c, eval.c,
findvar.c, infcmd.c, infptrace.c, infrun.c, m2-exp.y, parse.c,
putenv.c, solib.c, sparc-xdep.c, symtab.c, tm-i386v.h, tm-sparc.h,
utils.c, valarith.c, valops.c, valprint.c, values.c:
Replace bcopy() use with memcpy(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
* breakpoint.c, buildsym.c, coffread.c, dbxread.c, i386-tdep.c,
ieee-float.c, infcmd.c, sparc-tdep.c, stack.c, symtab.c, symtab.h,
target.c, values.c:
Replace bzero() use with memset(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
* i386-tdep.c, main.c, valprint.c:
Replace bcmp() use with memcmp(), which is more standard and can
take advantage of gcc's builtin functions for increased performance.
1992-06-29 23:34:38 +00:00
|
|
|
|
register int j;
|
1991-03-28 16:28:29 +00:00
|
|
|
|
unsigned char *translate = (unsigned char *) bufp->translate;
|
|
|
|
|
|
|
|
|
|
unsigned char *stackb[NFAILURES];
|
|
|
|
|
unsigned char **stackp = stackb;
|
|
|
|
|
|
1993-09-01 21:56:42 +00:00
|
|
|
|
memset (fastmap, '\0', (1 << BYTEWIDTH));
|
1991-03-28 16:28:29 +00:00
|
|
|
|
bufp->fastmap_accurate = 1;
|
|
|
|
|
bufp->can_be_null = 0;
|
|
|
|
|
|
|
|
|
|
while (p)
|
|
|
|
|
{
|
|
|
|
|
if (p == pend)
|
|
|
|
|
{
|
|
|
|
|
bufp->can_be_null = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#ifdef SWITCH_ENUM_BUG
|
|
|
|
|
switch ((int) ((enum regexpcode) *p++))
|
|
|
|
|
#else
|
|
|
|
|
switch ((enum regexpcode) *p++)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
case exactn:
|
|
|
|
|
if (translate)
|
|
|
|
|
fastmap[translate[p[1]]] = 1;
|
|
|
|
|
else
|
|
|
|
|
fastmap[p[1]] = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case begline:
|
|
|
|
|
case before_dot:
|
|
|
|
|
case at_dot:
|
|
|
|
|
case after_dot:
|
|
|
|
|
case begbuf:
|
|
|
|
|
case endbuf:
|
|
|
|
|
case wordbound:
|
|
|
|
|
case notwordbound:
|
|
|
|
|
case wordbeg:
|
|
|
|
|
case wordend:
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case endline:
|
|
|
|
|
if (translate)
|
|
|
|
|
fastmap[translate['\n']] = 1;
|
|
|
|
|
else
|
|
|
|
|
fastmap['\n'] = 1;
|
|
|
|
|
if (bufp->can_be_null != 1)
|
|
|
|
|
bufp->can_be_null = 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case finalize_jump:
|
|
|
|
|
case maybe_finalize_jump:
|
|
|
|
|
case jump:
|
|
|
|
|
case dummy_failure_jump:
|
|
|
|
|
bufp->can_be_null = 1;
|
|
|
|
|
j = *p++ & 0377;
|
|
|
|
|
j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p += j + 1; /* The 1 compensates for missing ++ above */
|
|
|
|
|
if (j > 0)
|
|
|
|
|
continue;
|
|
|
|
|
/* Jump backward reached implies we just went through
|
|
|
|
|
the body of a loop and matched nothing.
|
|
|
|
|
Opcode jumped to should be an on_failure_jump.
|
|
|
|
|
Just treat it like an ordinary jump.
|
|
|
|
|
For a * loop, it has pushed its failure point already;
|
|
|
|
|
if so, discard that as redundant. */
|
|
|
|
|
if ((enum regexpcode) *p != on_failure_jump)
|
|
|
|
|
continue;
|
|
|
|
|
p++;
|
|
|
|
|
j = *p++ & 0377;
|
|
|
|
|
j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p += j + 1; /* The 1 compensates for missing ++ above */
|
|
|
|
|
if (stackp != stackb && *stackp == p)
|
|
|
|
|
stackp--;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case on_failure_jump:
|
|
|
|
|
j = *p++ & 0377;
|
|
|
|
|
j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p++;
|
|
|
|
|
*++stackp = p + j;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case start_memory:
|
|
|
|
|
case stop_memory:
|
|
|
|
|
p++;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case duplicate:
|
|
|
|
|
bufp->can_be_null = 1;
|
|
|
|
|
fastmap['\n'] = 1;
|
|
|
|
|
case anychar:
|
|
|
|
|
for (j = 0; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (j != '\n')
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
if (bufp->can_be_null)
|
|
|
|
|
return;
|
|
|
|
|
/* Don't return; check the alternative paths
|
|
|
|
|
so we can set can_be_null if appropriate. */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case wordchar:
|
|
|
|
|
for (j = 0; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (SYNTAX (j) == Sword)
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case notwordchar:
|
|
|
|
|
for (j = 0; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (SYNTAX (j) != Sword)
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#ifdef emacs
|
|
|
|
|
case syntaxspec:
|
|
|
|
|
k = *p++;
|
|
|
|
|
for (j = 0; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (SYNTAX (j) == (enum syntaxcode) k)
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case notsyntaxspec:
|
|
|
|
|
k = *p++;
|
|
|
|
|
for (j = 0; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (SYNTAX (j) != (enum syntaxcode) k)
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
break;
|
|
|
|
|
#endif /* emacs */
|
|
|
|
|
|
|
|
|
|
case charset:
|
|
|
|
|
for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
|
|
|
|
|
if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
|
|
|
|
|
{
|
|
|
|
|
if (translate)
|
|
|
|
|
fastmap[translate[j]] = 1;
|
|
|
|
|
else
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case charset_not:
|
|
|
|
|
/* Chars beyond end of map must be allowed */
|
|
|
|
|
for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
|
|
|
|
|
if (translate)
|
|
|
|
|
fastmap[translate[j]] = 1;
|
|
|
|
|
else
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
|
|
|
|
|
for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
|
|
|
|
|
if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
|
|
|
|
|
{
|
|
|
|
|
if (translate)
|
|
|
|
|
fastmap[translate[j]] = 1;
|
|
|
|
|
else
|
|
|
|
|
fastmap[j] = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
* dache.c (struct dcache_block): Change data member from unsigned char
to char, since everything passed in and out of dcache is char or casted
to appropriate type anyway.
(dcache_alloc): Move assignment of db out of test and combine separate
tests into if-else.
(dcache_peek_byte): Change ptr from unsigned char* to char*.
(dcache_peek_byte): Remove now unnecessary cast in read_memory call.
(dcache_peek): Change cast of incoming data arg.
(dcache_poke): Change cast of addr of incoming data arg.
(dcache_info): Mask data passed to printf_filtered to lsbyte only.
(dcache_info): Change printf_filtered arg from "% 2x" to " %2x".
* target.c (debug_to_thread_alive): Change return type to int and
return zero, for type compatibility with other *_thread_alive funcs.
(cleanup_target): Change cast of ignore function to match type of the
to_thread_alive member.
* defs.h (error_hook): Add ATTR_NORETURN.
* defs.h (NORETURN, ATTR_NORETURN): Switch from volatile to
__attribute__ method with gcc 2.7, to avoid gcc 2.6.3 bug.
* remote.c (remote_wait): Cast first arg to strtol, strchr, and strncmp
to "const char *" from "unsigned char *".
(remote_wait): Cast arg to putpkt and strcpy from "unsigned char *" to
"char *".
(remote_wait): Change printf format for long arg from "%d" to "%ld".
(getpkt): Remove unused variable "bp".
(remote_fetch_word, remote_store_word): Ifdef out apparently unused
functions.
* breakpoint.c (watchpoint_check): Removed unused variables
"saved_level" and "saved_frame".
* valops.c (value_arg_coerce): Add other enum TYPE_CODE_* and
default cases to switch for completeness.
* infrun.c (wait_for_inferior): Enclose "have_waited" label
in #ifdef that matches the one in which it is referenced.
* ser-unix.c (hardwire_noflush_set_tty_state): Enclose otherwise
unused variable "state" in #ifdef that matches one in which it is
referenced.
* eval.c (evaluate_subexp_standard): Remove unused variable "var".
* eval.c (evaluate_subexp_standard): Remove unused variable "tmp_symbol".
* valarith.c (value_subscript): Remove unused variable "lowerbound",
which is redeclared in a nested scope prior to use.
* printcmd.c (print_frame_nameless_args): Use "%ld" to print long
arg, not "%d".
* {mem-break.c, remote-pa.c, remote.c, saber.suppress}:
Remove unused static var "check_break_insn_size".
* buildsym.c (finish_block): Add other enum LOC_* and default
cases to switch for completeness.
ch-lang.c (type_lower_upper): Removed unused label "retry".
Add other enum TYPE_* and default cases to switch for completeness.
* f-typeprint.c (f_type_print_args): Ifdef out unused function
that may be used someday when Fortran support is complete.
* ch-valprint.c (chill_print_type_scalar): Add other enum
TYPE_* and default cases to switch for completeness.
(chill_val_print): Remove unused local var "high_bound" that
is redeclared in a nested scope prior to use.
(chill_var_print): Use "%ld" to print long arg, not "%d".
* regex.c (re_compile_fastmap, re_match_2): Add remaining enum types
and default to switches for completeness.
* minsyms.c (lookup_minimal_symbol_text): Delete unused variable
"trampoline_symbol".
(prim_record_minimal_symbol_and_info): Return NULL rather than trash.
* elfread.c (elf_symtab_read): Don't dereference NULL returns from
record_minimal_symbol_and_info.
* f-lang.c (saved_function_list_end): Ifdef out unused variable
that may be used someday.
* f-valprint.c (f_val_print): Remove unused local variable "straddr".
1995-07-18 04:38:06 +00:00
|
|
|
|
case unused:
|
|
|
|
|
case syntaxspec:
|
|
|
|
|
case notsyntaxspec:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get here means we have successfully found the possible starting characters
|
|
|
|
|
of one path of the pattern. We need not follow this path any farther.
|
|
|
|
|
Instead, look at the next alternative remembered in the stack. */
|
|
|
|
|
if (stackp != stackb)
|
|
|
|
|
p = *stackp--;
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Like re_search_2, below, but only one string is specified. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
re_search (pbufp, string, size, startpos, range, regs)
|
|
|
|
|
struct re_pattern_buffer *pbufp;
|
|
|
|
|
char *string;
|
|
|
|
|
int size, startpos, range;
|
|
|
|
|
struct re_registers *regs;
|
|
|
|
|
{
|
|
|
|
|
return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Like re_match_2 but tries first a match starting at index STARTPOS,
|
|
|
|
|
then at STARTPOS + 1, and so on.
|
|
|
|
|
RANGE is the number of places to try before giving up.
|
|
|
|
|
If RANGE is negative, the starting positions tried are
|
|
|
|
|
STARTPOS, STARTPOS - 1, etc.
|
|
|
|
|
It is up to the caller to make sure that range is not so large
|
|
|
|
|
as to take the starting position outside of the input strings.
|
|
|
|
|
|
|
|
|
|
The value returned is the position at which the match was found,
|
|
|
|
|
or -1 if no match was found,
|
|
|
|
|
or -2 if error (such as failure stack overflow). */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
re_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop)
|
|
|
|
|
struct re_pattern_buffer *pbufp;
|
|
|
|
|
char *string1, *string2;
|
|
|
|
|
int size1, size2;
|
|
|
|
|
int startpos;
|
|
|
|
|
register int range;
|
|
|
|
|
struct re_registers *regs;
|
|
|
|
|
int mstop;
|
|
|
|
|
{
|
|
|
|
|
register char *fastmap = pbufp->fastmap;
|
|
|
|
|
register unsigned char *translate = (unsigned char *) pbufp->translate;
|
|
|
|
|
int total = size1 + size2;
|
|
|
|
|
int val;
|
|
|
|
|
|
|
|
|
|
/* Update the fastmap now if not correct already */
|
|
|
|
|
if (fastmap && !pbufp->fastmap_accurate)
|
|
|
|
|
re_compile_fastmap (pbufp);
|
|
|
|
|
|
|
|
|
|
/* Don't waste time in a long search for a pattern
|
|
|
|
|
that says it is anchored. */
|
|
|
|
|
if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
|
|
|
|
|
&& range > 0)
|
|
|
|
|
{
|
|
|
|
|
if (startpos > 0)
|
|
|
|
|
return -1;
|
|
|
|
|
else
|
|
|
|
|
range = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
/* If a fastmap is supplied, skip quickly over characters
|
|
|
|
|
that cannot possibly be the start of a match.
|
|
|
|
|
Note, however, that if the pattern can possibly match
|
|
|
|
|
the null string, we must test it at each starting point
|
|
|
|
|
so that we take the first null string we get. */
|
|
|
|
|
|
|
|
|
|
if (fastmap && startpos < total && pbufp->can_be_null != 1)
|
|
|
|
|
{
|
|
|
|
|
if (range > 0)
|
|
|
|
|
{
|
|
|
|
|
register int lim = 0;
|
|
|
|
|
register unsigned char *p;
|
|
|
|
|
int irange = range;
|
|
|
|
|
if (startpos < size1 && startpos + range >= size1)
|
|
|
|
|
lim = range - (size1 - startpos);
|
|
|
|
|
|
|
|
|
|
p = ((unsigned char *)
|
|
|
|
|
&(startpos >= size1 ? string2 - size1 : string1)[startpos]);
|
|
|
|
|
|
|
|
|
|
if (translate)
|
|
|
|
|
{
|
|
|
|
|
while (range > lim && !fastmap[translate[*p++]])
|
|
|
|
|
range--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while (range > lim && !fastmap[*p++])
|
|
|
|
|
range--;
|
|
|
|
|
}
|
|
|
|
|
startpos += irange - range;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
register unsigned char c;
|
|
|
|
|
if (startpos >= size1)
|
|
|
|
|
c = string2[startpos - size1];
|
|
|
|
|
else
|
|
|
|
|
c = string1[startpos];
|
|
|
|
|
c &= 0xff;
|
|
|
|
|
if (translate ? !fastmap[translate[c]] : !fastmap[c])
|
|
|
|
|
goto advance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (range >= 0 && startpos == total
|
|
|
|
|
&& fastmap && pbufp->can_be_null == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
val = re_match_2 (pbufp, string1, size1, string2, size2, startpos, regs, mstop);
|
|
|
|
|
if (0 <= val)
|
|
|
|
|
{
|
|
|
|
|
if (val == -2)
|
|
|
|
|
return -2;
|
|
|
|
|
return startpos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef C_ALLOCA
|
|
|
|
|
alloca (0);
|
|
|
|
|
#endif /* C_ALLOCA */
|
|
|
|
|
|
|
|
|
|
advance:
|
|
|
|
|
if (!range) break;
|
|
|
|
|
if (range > 0) range--, startpos++; else range++, startpos--;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef emacs /* emacs never uses this */
|
|
|
|
|
int
|
|
|
|
|
re_match (pbufp, string, size, pos, regs)
|
|
|
|
|
struct re_pattern_buffer *pbufp;
|
|
|
|
|
char *string;
|
|
|
|
|
int size, pos;
|
|
|
|
|
struct re_registers *regs;
|
|
|
|
|
{
|
|
|
|
|
return re_match_2 (pbufp, 0, 0, string, size, pos, regs, size);
|
|
|
|
|
}
|
|
|
|
|
#endif /* emacs */
|
|
|
|
|
|
|
|
|
|
/* Maximum size of failure stack. Beyond this, overflow is an error. */
|
|
|
|
|
|
|
|
|
|
int re_max_failures = 2000;
|
|
|
|
|
|
1993-09-01 21:43:56 +00:00
|
|
|
|
static int memcmp_translate();
|
1991-03-28 16:28:29 +00:00
|
|
|
|
/* Match the pattern described by PBUFP
|
|
|
|
|
against data which is the virtual concatenation of STRING1 and STRING2.
|
|
|
|
|
SIZE1 and SIZE2 are the sizes of the two data strings.
|
|
|
|
|
Start the match at position POS.
|
|
|
|
|
Do not consider matching past the position MSTOP.
|
|
|
|
|
|
|
|
|
|
If pbufp->fastmap is nonzero, then it had better be up to date.
|
|
|
|
|
|
|
|
|
|
The reason that the data to match are specified as two components
|
|
|
|
|
which are to be regarded as concatenated
|
|
|
|
|
is so this function can be used directly on the contents of an Emacs buffer.
|
|
|
|
|
|
|
|
|
|
-1 is returned if there is no match. -2 is returned if there is
|
|
|
|
|
an error (such as match stack overflow). Otherwise the value is the length
|
|
|
|
|
of the substring which was matched. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
re_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
|
|
|
|
|
struct re_pattern_buffer *pbufp;
|
|
|
|
|
unsigned char *string1, *string2;
|
|
|
|
|
int size1, size2;
|
|
|
|
|
int pos;
|
|
|
|
|
struct re_registers *regs;
|
|
|
|
|
int mstop;
|
|
|
|
|
{
|
|
|
|
|
register unsigned char *p = (unsigned char *) pbufp->buffer;
|
|
|
|
|
register unsigned char *pend = p + pbufp->used;
|
|
|
|
|
/* End of first string */
|
|
|
|
|
unsigned char *end1;
|
|
|
|
|
/* End of second string */
|
|
|
|
|
unsigned char *end2;
|
|
|
|
|
/* Pointer just past last char to consider matching */
|
|
|
|
|
unsigned char *end_match_1, *end_match_2;
|
|
|
|
|
register unsigned char *d, *dend;
|
|
|
|
|
register int mcnt;
|
|
|
|
|
unsigned char *translate = (unsigned char *) pbufp->translate;
|
|
|
|
|
|
|
|
|
|
/* Failure point stack. Each place that can handle a failure further down the line
|
|
|
|
|
pushes a failure point on this stack. It consists of two char *'s.
|
|
|
|
|
The first one pushed is where to resume scanning the pattern;
|
|
|
|
|
the second pushed is where to resume scanning the strings.
|
|
|
|
|
If the latter is zero, the failure point is a "dummy".
|
|
|
|
|
If a failure happens and the innermost failure point is dormant,
|
|
|
|
|
it discards that failure point and tries the next one. */
|
|
|
|
|
|
|
|
|
|
unsigned char *initial_stack[2 * NFAILURES];
|
|
|
|
|
unsigned char **stackb = initial_stack;
|
|
|
|
|
unsigned char **stackp = stackb, **stacke = &stackb[2 * NFAILURES];
|
|
|
|
|
|
|
|
|
|
/* Information on the "contents" of registers.
|
|
|
|
|
These are pointers into the input strings; they record
|
|
|
|
|
just what was matched (on this attempt) by some part of the pattern.
|
|
|
|
|
The start_memory command stores the start of a register's contents
|
|
|
|
|
and the stop_memory command stores the end.
|
|
|
|
|
|
|
|
|
|
At that point, regstart[regnum] points to the first character in the register,
|
|
|
|
|
regend[regnum] points to the first character beyond the end of the register,
|
|
|
|
|
regstart_seg1[regnum] is true iff regstart[regnum] points into string1,
|
|
|
|
|
and regend_seg1[regnum] is true iff regend[regnum] points into string1. */
|
|
|
|
|
|
|
|
|
|
unsigned char *regstart[RE_NREGS];
|
|
|
|
|
unsigned char *regend[RE_NREGS];
|
|
|
|
|
unsigned char regstart_seg1[RE_NREGS], regend_seg1[RE_NREGS];
|
|
|
|
|
|
|
|
|
|
/* Set up pointers to ends of strings.
|
|
|
|
|
Don't allow the second string to be empty unless both are empty. */
|
|
|
|
|
if (!size2)
|
|
|
|
|
{
|
|
|
|
|
string2 = string1;
|
|
|
|
|
size2 = size1;
|
|
|
|
|
string1 = 0;
|
|
|
|
|
size1 = 0;
|
|
|
|
|
}
|
|
|
|
|
end1 = string1 + size1;
|
|
|
|
|
end2 = string2 + size2;
|
|
|
|
|
|
|
|
|
|
/* Compute where to stop matching, within the two strings */
|
|
|
|
|
if (mstop <= size1)
|
|
|
|
|
{
|
|
|
|
|
end_match_1 = string1 + mstop;
|
|
|
|
|
end_match_2 = string2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
end_match_1 = end1;
|
|
|
|
|
end_match_2 = string2 + mstop - size1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize \) text positions to -1
|
|
|
|
|
to mark ones that no \( or \) has been seen for. */
|
|
|
|
|
|
|
|
|
|
for (mcnt = 0; mcnt < sizeof (regend) / sizeof (*regend); mcnt++)
|
|
|
|
|
regend[mcnt] = (unsigned char *) -1;
|
|
|
|
|
|
|
|
|
|
/* `p' scans through the pattern as `d' scans through the data.
|
|
|
|
|
`dend' is the end of the input string that `d' points within.
|
|
|
|
|
`d' is advanced into the following input string whenever necessary,
|
|
|
|
|
but this happens before fetching;
|
|
|
|
|
therefore, at the beginning of the loop,
|
|
|
|
|
`d' can be pointing at the end of a string,
|
|
|
|
|
but it cannot equal string2. */
|
|
|
|
|
|
|
|
|
|
if (pos <= size1)
|
|
|
|
|
d = string1 + pos, dend = end_match_1;
|
|
|
|
|
else
|
|
|
|
|
d = string2 + pos - size1, dend = end_match_2;
|
|
|
|
|
|
|
|
|
|
/* Write PREFETCH; just before fetching a character with *d. */
|
|
|
|
|
#define PREFETCH \
|
|
|
|
|
while (d == dend) \
|
|
|
|
|
{ if (dend == end_match_2) goto fail; /* end of string2 => failure */ \
|
|
|
|
|
d = string2; /* end of string1 => advance to string2. */ \
|
|
|
|
|
dend = end_match_2; }
|
|
|
|
|
|
|
|
|
|
/* This loop loops over pattern commands.
|
|
|
|
|
It exits by returning from the function if match is complete,
|
|
|
|
|
or it drops through if match fails at this starting point in the input data. */
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (p == pend)
|
|
|
|
|
/* End of pattern means we have succeeded! */
|
|
|
|
|
{
|
|
|
|
|
/* If caller wants register contents data back, convert it to indices */
|
|
|
|
|
if (regs)
|
|
|
|
|
{
|
|
|
|
|
regs->start[0] = pos;
|
|
|
|
|
if (dend == end_match_1)
|
|
|
|
|
regs->end[0] = d - string1;
|
|
|
|
|
else
|
|
|
|
|
regs->end[0] = d - string2 + size1;
|
|
|
|
|
for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
|
|
|
|
|
{
|
|
|
|
|
if (regend[mcnt] == (unsigned char *) -1)
|
|
|
|
|
{
|
|
|
|
|
regs->start[mcnt] = -1;
|
|
|
|
|
regs->end[mcnt] = -1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (regstart_seg1[mcnt])
|
|
|
|
|
regs->start[mcnt] = regstart[mcnt] - string1;
|
|
|
|
|
else
|
|
|
|
|
regs->start[mcnt] = regstart[mcnt] - string2 + size1;
|
|
|
|
|
if (regend_seg1[mcnt])
|
|
|
|
|
regs->end[mcnt] = regend[mcnt] - string1;
|
|
|
|
|
else
|
|
|
|
|
regs->end[mcnt] = regend[mcnt] - string2 + size1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (dend == end_match_1)
|
|
|
|
|
return (d - string1 - pos);
|
|
|
|
|
else
|
|
|
|
|
return d - string2 + size1 - pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise match next pattern command */
|
|
|
|
|
#ifdef SWITCH_ENUM_BUG
|
|
|
|
|
switch ((int) ((enum regexpcode) *p++))
|
|
|
|
|
#else
|
|
|
|
|
switch ((enum regexpcode) *p++)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* \( is represented by a start_memory, \) by a stop_memory.
|
|
|
|
|
Both of those commands contain a "register number" argument.
|
|
|
|
|
The text matched within the \( and \) is recorded under that number.
|
|
|
|
|
Then, \<digit> turns into a `duplicate' command which
|
|
|
|
|
is followed by the numeric value of <digit> as the register number. */
|
|
|
|
|
|
|
|
|
|
case start_memory:
|
|
|
|
|
regstart[*p] = d;
|
|
|
|
|
regstart_seg1[*p++] = (dend == end_match_1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case stop_memory:
|
|
|
|
|
regend[*p] = d;
|
|
|
|
|
regend_seg1[*p++] = (dend == end_match_1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case duplicate:
|
|
|
|
|
{
|
|
|
|
|
int regno = *p++; /* Get which register to match against */
|
|
|
|
|
register unsigned char *d2, *dend2;
|
|
|
|
|
|
|
|
|
|
d2 = regstart[regno];
|
|
|
|
|
dend2 = ((regstart_seg1[regno] == regend_seg1[regno])
|
|
|
|
|
? regend[regno] : end_match_1);
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
/* Advance to next segment in register contents, if necessary */
|
|
|
|
|
while (d2 == dend2)
|
|
|
|
|
{
|
|
|
|
|
if (dend2 == end_match_2) break;
|
|
|
|
|
if (dend2 == regend[regno]) break;
|
|
|
|
|
d2 = string2, dend2 = regend[regno]; /* end of string1 => advance to string2. */
|
|
|
|
|
}
|
|
|
|
|
/* At end of register contents => success */
|
|
|
|
|
if (d2 == dend2) break;
|
|
|
|
|
|
|
|
|
|
/* Advance to next segment in data being matched, if necessary */
|
|
|
|
|
PREFETCH;
|
|
|
|
|
|
|
|
|
|
/* mcnt gets # consecutive chars to compare */
|
|
|
|
|
mcnt = dend - d;
|
|
|
|
|
if (mcnt > dend2 - d2)
|
|
|
|
|
mcnt = dend2 - d2;
|
|
|
|
|
/* Compare that many; failure if mismatch, else skip them. */
|
1993-09-01 21:43:56 +00:00
|
|
|
|
if (translate ? memcmp_translate (d, d2, mcnt, translate) : memcmp (d, d2, mcnt))
|
1991-03-28 16:28:29 +00:00
|
|
|
|
goto fail;
|
|
|
|
|
d += mcnt, d2 += mcnt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case anychar:
|
|
|
|
|
/* fetch a data character */
|
|
|
|
|
PREFETCH;
|
|
|
|
|
/* Match anything but a newline. */
|
|
|
|
|
if ((translate ? translate[*d++] : *d++) == '\n')
|
|
|
|
|
goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case charset:
|
|
|
|
|
case charset_not:
|
|
|
|
|
{
|
|
|
|
|
/* Nonzero for charset_not */
|
|
|
|
|
int not = 0;
|
|
|
|
|
register int c;
|
|
|
|
|
if (*(p - 1) == (unsigned char) charset_not)
|
|
|
|
|
not = 1;
|
|
|
|
|
|
|
|
|
|
/* fetch a data character */
|
|
|
|
|
PREFETCH;
|
|
|
|
|
|
|
|
|
|
if (translate)
|
|
|
|
|
c = translate [*d];
|
|
|
|
|
else
|
|
|
|
|
c = *d;
|
|
|
|
|
|
|
|
|
|
if (c < *p * BYTEWIDTH
|
|
|
|
|
&& p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
|
|
|
|
|
not = !not;
|
|
|
|
|
|
|
|
|
|
p += 1 + *p;
|
|
|
|
|
|
|
|
|
|
if (!not) goto fail;
|
|
|
|
|
d++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case begline:
|
|
|
|
|
if (d == string1 || d[-1] == '\n')
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
case endline:
|
|
|
|
|
if (d == end2
|
|
|
|
|
|| (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* "or" constructs ("|") are handled by starting each alternative
|
|
|
|
|
with an on_failure_jump that points to the start of the next alternative.
|
|
|
|
|
Each alternative except the last ends with a jump to the joining point.
|
|
|
|
|
(Actually, each jump except for the last one really jumps
|
|
|
|
|
to the following jump, because tensioning the jumps is a hassle.) */
|
|
|
|
|
|
|
|
|
|
/* The start of a stupid repeat has an on_failure_jump that points
|
|
|
|
|
past the end of the repeat text.
|
|
|
|
|
This makes a failure point so that, on failure to match a repetition,
|
|
|
|
|
matching restarts past as many repetitions have been found
|
|
|
|
|
with no way to fail and look for another one. */
|
|
|
|
|
|
|
|
|
|
/* A smart repeat is similar but loops back to the on_failure_jump
|
|
|
|
|
so that each repetition makes another failure point. */
|
|
|
|
|
|
|
|
|
|
case on_failure_jump:
|
|
|
|
|
if (stackp == stacke)
|
|
|
|
|
{
|
|
|
|
|
unsigned char **stackx;
|
|
|
|
|
if (stacke - stackb > re_max_failures * 2)
|
|
|
|
|
return -2;
|
|
|
|
|
stackx = (unsigned char **) alloca (2 * (stacke - stackb)
|
|
|
|
|
* sizeof (char *));
|
1993-09-01 20:37:15 +00:00
|
|
|
|
memcpy (stackx, stackb, (stacke - stackb) * sizeof (char *));
|
1991-03-28 16:28:29 +00:00
|
|
|
|
stackp = stackx + (stackp - stackb);
|
|
|
|
|
stacke = stackx + 2 * (stacke - stackb);
|
|
|
|
|
stackb = stackx;
|
|
|
|
|
}
|
|
|
|
|
mcnt = *p++ & 0377;
|
|
|
|
|
mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p++;
|
|
|
|
|
*stackp++ = mcnt + p;
|
|
|
|
|
*stackp++ = d;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* The end of a smart repeat has an maybe_finalize_jump back.
|
|
|
|
|
Change it either to a finalize_jump or an ordinary jump. */
|
|
|
|
|
|
|
|
|
|
case maybe_finalize_jump:
|
|
|
|
|
mcnt = *p++ & 0377;
|
|
|
|
|
mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p++;
|
|
|
|
|
{
|
|
|
|
|
register unsigned char *p2 = p;
|
|
|
|
|
/* Compare what follows with the begining of the repeat.
|
|
|
|
|
If we can establish that there is nothing that they would
|
|
|
|
|
both match, we can change to finalize_jump */
|
|
|
|
|
while (p2 != pend
|
|
|
|
|
&& (*p2 == (unsigned char) stop_memory
|
|
|
|
|
|| *p2 == (unsigned char) start_memory))
|
|
|
|
|
p2++;
|
|
|
|
|
if (p2 == pend)
|
|
|
|
|
p[-3] = (unsigned char) finalize_jump;
|
|
|
|
|
else if (*p2 == (unsigned char) exactn
|
|
|
|
|
|| *p2 == (unsigned char) endline)
|
|
|
|
|
{
|
|
|
|
|
register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
|
|
|
|
|
register unsigned char *p1 = p + mcnt;
|
|
|
|
|
/* p1[0] ... p1[2] are an on_failure_jump.
|
|
|
|
|
Examine what follows that */
|
|
|
|
|
if (p1[3] == (unsigned char) exactn && p1[5] != c)
|
|
|
|
|
p[-3] = (unsigned char) finalize_jump;
|
|
|
|
|
else if (p1[3] == (unsigned char) charset
|
|
|
|
|
|| p1[3] == (unsigned char) charset_not)
|
|
|
|
|
{
|
|
|
|
|
int not = p1[3] == (unsigned char) charset_not;
|
|
|
|
|
if (c < p1[4] * BYTEWIDTH
|
|
|
|
|
&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
|
|
|
|
|
not = !not;
|
|
|
|
|
/* not is 1 if c would match */
|
|
|
|
|
/* That means it is not safe to finalize */
|
|
|
|
|
if (!not)
|
|
|
|
|
p[-3] = (unsigned char) finalize_jump;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p -= 2;
|
|
|
|
|
if (p[-1] != (unsigned char) finalize_jump)
|
|
|
|
|
{
|
|
|
|
|
p[-1] = (unsigned char) jump;
|
|
|
|
|
goto nofinalize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The end of a stupid repeat has a finalize-jump
|
|
|
|
|
back to the start, where another failure point will be made
|
|
|
|
|
which will point after all the repetitions found so far. */
|
|
|
|
|
|
|
|
|
|
case finalize_jump:
|
|
|
|
|
stackp -= 2;
|
|
|
|
|
|
|
|
|
|
case jump:
|
|
|
|
|
nofinalize:
|
|
|
|
|
mcnt = *p++ & 0377;
|
|
|
|
|
mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
|
|
|
|
|
p += mcnt + 1; /* The 1 compensates for missing ++ above */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case dummy_failure_jump:
|
|
|
|
|
if (stackp == stacke)
|
|
|
|
|
{
|
|
|
|
|
unsigned char **stackx
|
|
|
|
|
= (unsigned char **) alloca (2 * (stacke - stackb)
|
|
|
|
|
* sizeof (char *));
|
1993-09-01 20:37:15 +00:00
|
|
|
|
memcpy (stackx, stackb, (stacke - stackb) * sizeof (char *));
|
1991-03-28 16:28:29 +00:00
|
|
|
|
stackp = stackx + (stackp - stackb);
|
|
|
|
|
stacke = stackx + 2 * (stacke - stackb);
|
|
|
|
|
stackb = stackx;
|
|
|
|
|
}
|
|
|
|
|
*stackp++ = 0;
|
|
|
|
|
*stackp++ = 0;
|
|
|
|
|
goto nofinalize;
|
|
|
|
|
|
|
|
|
|
case wordbound:
|
|
|
|
|
if (d == string1 /* Points to first char */
|
|
|
|
|
|| d == end2 /* Points to end */
|
|
|
|
|
|| (d == end1 && size2 == 0)) /* Points to end */
|
|
|
|
|
break;
|
|
|
|
|
if ((SYNTAX (d[-1]) == Sword)
|
|
|
|
|
!= (SYNTAX (d == end1 ? *string2 : *d) == Sword))
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
case notwordbound:
|
|
|
|
|
if (d == string1 /* Points to first char */
|
|
|
|
|
|| d == end2 /* Points to end */
|
|
|
|
|
|| (d == end1 && size2 == 0)) /* Points to end */
|
|
|
|
|
goto fail;
|
|
|
|
|
if ((SYNTAX (d[-1]) == Sword)
|
|
|
|
|
!= (SYNTAX (d == end1 ? *string2 : *d) == Sword))
|
|
|
|
|
goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case wordbeg:
|
|
|
|
|
if (d == end2 /* Points to end */
|
|
|
|
|
|| (d == end1 && size2 == 0) /* Points to end */
|
|
|
|
|
|| SYNTAX (* (d == end1 ? string2 : d)) != Sword) /* Next char not a letter */
|
|
|
|
|
goto fail;
|
|
|
|
|
if (d == string1 /* Points to first char */
|
|
|
|
|
|| SYNTAX (d[-1]) != Sword) /* prev char not letter */
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
case wordend:
|
|
|
|
|
if (d == string1 /* Points to first char */
|
|
|
|
|
|| SYNTAX (d[-1]) != Sword) /* prev char not letter */
|
|
|
|
|
goto fail;
|
|
|
|
|
if (d == end2 /* Points to end */
|
|
|
|
|
|| (d == end1 && size2 == 0) /* Points to end */
|
|
|
|
|
|| SYNTAX (d == end1 ? *string2 : *d) != Sword) /* Next char not a letter */
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
#ifdef emacs
|
|
|
|
|
case before_dot:
|
|
|
|
|
if (((d - string2 <= (unsigned) size2)
|
|
|
|
|
? d - bf_p2 : d - bf_p1)
|
|
|
|
|
<= point)
|
|
|
|
|
goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case at_dot:
|
|
|
|
|
if (((d - string2 <= (unsigned) size2)
|
|
|
|
|
? d - bf_p2 : d - bf_p1)
|
|
|
|
|
== point)
|
|
|
|
|
goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case after_dot:
|
|
|
|
|
if (((d - string2 <= (unsigned) size2)
|
|
|
|
|
? d - bf_p2 : d - bf_p1)
|
|
|
|
|
>= point)
|
|
|
|
|
goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case wordchar:
|
|
|
|
|
mcnt = (int) Sword;
|
|
|
|
|
goto matchsyntax;
|
|
|
|
|
|
|
|
|
|
case syntaxspec:
|
|
|
|
|
mcnt = *p++;
|
|
|
|
|
matchsyntax:
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case notwordchar:
|
|
|
|
|
mcnt = (int) Sword;
|
|
|
|
|
goto matchnotsyntax;
|
|
|
|
|
|
|
|
|
|
case notsyntaxspec:
|
|
|
|
|
mcnt = *p++;
|
|
|
|
|
matchnotsyntax:
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
|
|
|
|
|
break;
|
|
|
|
|
#else
|
|
|
|
|
case wordchar:
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (SYNTAX (*d++) == 0) goto fail;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case notwordchar:
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (SYNTAX (*d++) != 0) goto fail;
|
|
|
|
|
break;
|
|
|
|
|
#endif /* not emacs */
|
|
|
|
|
|
|
|
|
|
case begbuf:
|
|
|
|
|
if (d == string1) /* Note, d cannot equal string2 */
|
|
|
|
|
break; /* unless string1 == string2. */
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
case endbuf:
|
|
|
|
|
if (d == end2 || (d == end1 && size2 == 0))
|
|
|
|
|
break;
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
case exactn:
|
|
|
|
|
/* Match the next few pattern characters exactly.
|
|
|
|
|
mcnt is how many characters to match. */
|
|
|
|
|
mcnt = *p++;
|
|
|
|
|
if (translate)
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (translate[*d++] != *p++) goto fail;
|
|
|
|
|
}
|
|
|
|
|
while (--mcnt);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
PREFETCH;
|
|
|
|
|
if (*d++ != *p++) goto fail;
|
|
|
|
|
}
|
|
|
|
|
while (--mcnt);
|
|
|
|
|
}
|
|
|
|
|
break;
|
* dache.c (struct dcache_block): Change data member from unsigned char
to char, since everything passed in and out of dcache is char or casted
to appropriate type anyway.
(dcache_alloc): Move assignment of db out of test and combine separate
tests into if-else.
(dcache_peek_byte): Change ptr from unsigned char* to char*.
(dcache_peek_byte): Remove now unnecessary cast in read_memory call.
(dcache_peek): Change cast of incoming data arg.
(dcache_poke): Change cast of addr of incoming data arg.
(dcache_info): Mask data passed to printf_filtered to lsbyte only.
(dcache_info): Change printf_filtered arg from "% 2x" to " %2x".
* target.c (debug_to_thread_alive): Change return type to int and
return zero, for type compatibility with other *_thread_alive funcs.
(cleanup_target): Change cast of ignore function to match type of the
to_thread_alive member.
* defs.h (error_hook): Add ATTR_NORETURN.
* defs.h (NORETURN, ATTR_NORETURN): Switch from volatile to
__attribute__ method with gcc 2.7, to avoid gcc 2.6.3 bug.
* remote.c (remote_wait): Cast first arg to strtol, strchr, and strncmp
to "const char *" from "unsigned char *".
(remote_wait): Cast arg to putpkt and strcpy from "unsigned char *" to
"char *".
(remote_wait): Change printf format for long arg from "%d" to "%ld".
(getpkt): Remove unused variable "bp".
(remote_fetch_word, remote_store_word): Ifdef out apparently unused
functions.
* breakpoint.c (watchpoint_check): Removed unused variables
"saved_level" and "saved_frame".
* valops.c (value_arg_coerce): Add other enum TYPE_CODE_* and
default cases to switch for completeness.
* infrun.c (wait_for_inferior): Enclose "have_waited" label
in #ifdef that matches the one in which it is referenced.
* ser-unix.c (hardwire_noflush_set_tty_state): Enclose otherwise
unused variable "state" in #ifdef that matches one in which it is
referenced.
* eval.c (evaluate_subexp_standard): Remove unused variable "var".
* eval.c (evaluate_subexp_standard): Remove unused variable "tmp_symbol".
* valarith.c (value_subscript): Remove unused variable "lowerbound",
which is redeclared in a nested scope prior to use.
* printcmd.c (print_frame_nameless_args): Use "%ld" to print long
arg, not "%d".
* {mem-break.c, remote-pa.c, remote.c, saber.suppress}:
Remove unused static var "check_break_insn_size".
* buildsym.c (finish_block): Add other enum LOC_* and default
cases to switch for completeness.
ch-lang.c (type_lower_upper): Removed unused label "retry".
Add other enum TYPE_* and default cases to switch for completeness.
* f-typeprint.c (f_type_print_args): Ifdef out unused function
that may be used someday when Fortran support is complete.
* ch-valprint.c (chill_print_type_scalar): Add other enum
TYPE_* and default cases to switch for completeness.
(chill_val_print): Remove unused local var "high_bound" that
is redeclared in a nested scope prior to use.
(chill_var_print): Use "%ld" to print long arg, not "%d".
* regex.c (re_compile_fastmap, re_match_2): Add remaining enum types
and default to switches for completeness.
* minsyms.c (lookup_minimal_symbol_text): Delete unused variable
"trampoline_symbol".
(prim_record_minimal_symbol_and_info): Return NULL rather than trash.
* elfread.c (elf_symtab_read): Don't dereference NULL returns from
record_minimal_symbol_and_info.
* f-lang.c (saved_function_list_end): Ifdef out unused variable
that may be used someday.
* f-valprint.c (f_val_print): Remove unused local variable "straddr".
1995-07-18 04:38:06 +00:00
|
|
|
|
case unused:
|
|
|
|
|
case before_dot:
|
|
|
|
|
case at_dot:
|
|
|
|
|
case after_dot:
|
|
|
|
|
case syntaxspec:
|
|
|
|
|
case notsyntaxspec:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
continue; /* Successfully matched one pattern command; keep matching */
|
|
|
|
|
|
|
|
|
|
/* Jump here if any matching operation fails. */
|
|
|
|
|
fail:
|
|
|
|
|
if (stackp != stackb)
|
|
|
|
|
/* A restart point is known. Restart there and pop it. */
|
|
|
|
|
{
|
|
|
|
|
if (!stackp[-2])
|
|
|
|
|
{ /* If innermost failure point is dormant, flush it and keep looking */
|
|
|
|
|
stackp -= 2;
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
d = *--stackp;
|
|
|
|
|
p = *--stackp;
|
|
|
|
|
if (d >= string1 && d <= end1)
|
|
|
|
|
dend = end_match_1;
|
|
|
|
|
}
|
|
|
|
|
else break; /* Matching at this starting point really fails! */
|
|
|
|
|
}
|
|
|
|
|
return -1; /* Failure to match */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
1993-09-01 21:43:56 +00:00
|
|
|
|
memcmp_translate (s1, s2, len, translate)
|
1991-03-28 16:28:29 +00:00
|
|
|
|
unsigned char *s1, *s2;
|
|
|
|
|
register int len;
|
|
|
|
|
unsigned char *translate;
|
|
|
|
|
{
|
|
|
|
|
register unsigned char *p1 = s1, *p2 = s2;
|
|
|
|
|
while (len)
|
|
|
|
|
{
|
|
|
|
|
if (translate [*p1++] != translate [*p2++]) return 1;
|
|
|
|
|
len--;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Entry points compatible with bsd4.2 regex library */
|
|
|
|
|
|
|
|
|
|
#ifndef emacs
|
|
|
|
|
|
|
|
|
|
static struct re_pattern_buffer re_comp_buf;
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
re_comp (s)
|
* README: Remove note about gcc warnings on alpha, these should be
gone now.
* c-exp.y, ch-exp.y, core.c, corelow.c, eval.c, fork-child.c,
m2-exp.y, minsyms.c, nlmread.c, parse.c, putenv.c, regex.c
remote-utils.c, stabsread.c: Include <string.h>.
* regex.c: Include "defs.h", change re_comp argument to const char *.
* infptrace.c (fetch_register, store_inferior_registers): Change
regaddr to type CORE_ADDR.
* config/alpha/alpha-nw.mt, config/alpha/alpha-osf1.mt (MT_CFLAGS):
Remove, no longer necessary now that we use bfd_vma for a CORE_ADDR.
1994-02-08 09:01:03 +00:00
|
|
|
|
const char *s;
|
1991-03-28 16:28:29 +00:00
|
|
|
|
{
|
|
|
|
|
if (!s)
|
|
|
|
|
{
|
|
|
|
|
if (!re_comp_buf.buffer)
|
|
|
|
|
return "No previous regular expression";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!re_comp_buf.buffer)
|
|
|
|
|
{
|
|
|
|
|
if (!(re_comp_buf.buffer = (char *) malloc (200)))
|
|
|
|
|
return "Memory exhausted";
|
|
|
|
|
re_comp_buf.allocated = 200;
|
|
|
|
|
if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
|
|
|
|
|
return "Memory exhausted";
|
|
|
|
|
}
|
|
|
|
|
return re_compile_pattern (s, strlen (s), &re_comp_buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
re_exec (s)
|
|
|
|
|
char *s;
|
|
|
|
|
{
|
|
|
|
|
int len = strlen (s);
|
|
|
|
|
return 0 <= re_search (&re_comp_buf, s, len, 0, len, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* emacs */
|
|
|
|
|
|
|
|
|
|
#ifdef test
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
/* Indexed by a character, gives the upper case equivalent of the character */
|
|
|
|
|
|
|
|
|
|
static char upcase[0400] =
|
|
|
|
|
{ 000, 001, 002, 003, 004, 005, 006, 007,
|
|
|
|
|
010, 011, 012, 013, 014, 015, 016, 017,
|
|
|
|
|
020, 021, 022, 023, 024, 025, 026, 027,
|
|
|
|
|
030, 031, 032, 033, 034, 035, 036, 037,
|
|
|
|
|
040, 041, 042, 043, 044, 045, 046, 047,
|
|
|
|
|
050, 051, 052, 053, 054, 055, 056, 057,
|
|
|
|
|
060, 061, 062, 063, 064, 065, 066, 067,
|
|
|
|
|
070, 071, 072, 073, 074, 075, 076, 077,
|
|
|
|
|
0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
|
|
|
|
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
|
|
|
|
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
|
|
|
|
0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
|
|
|
|
|
0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
|
|
|
|
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
|
|
|
|
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
|
|
|
|
0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
|
|
|
|
|
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
|
|
|
|
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
|
|
|
|
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
|
|
|
|
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
|
|
|
|
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
|
|
|
|
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
|
|
|
|
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
|
|
|
|
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
|
|
|
|
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
|
|
|
|
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
|
|
|
|
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
|
|
|
|
|
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
|
|
|
|
|
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
|
|
|
|
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
|
|
|
|
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
|
|
|
|
|
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
main (argc, argv)
|
|
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
|
|
|
|
{
|
|
|
|
|
char pat[80];
|
|
|
|
|
struct re_pattern_buffer buf;
|
|
|
|
|
int i;
|
|
|
|
|
char c;
|
|
|
|
|
char fastmap[(1 << BYTEWIDTH)];
|
|
|
|
|
|
|
|
|
|
/* Allow a command argument to specify the style of syntax. */
|
|
|
|
|
if (argc > 1)
|
|
|
|
|
obscure_syntax = atoi (argv[1]);
|
|
|
|
|
|
|
|
|
|
buf.allocated = 40;
|
|
|
|
|
buf.buffer = (char *) malloc (buf.allocated);
|
|
|
|
|
buf.fastmap = fastmap;
|
|
|
|
|
buf.translate = upcase;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
gets (pat);
|
|
|
|
|
|
|
|
|
|
if (*pat)
|
|
|
|
|
{
|
|
|
|
|
re_compile_pattern (pat, strlen(pat), &buf);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < buf.used; i++)
|
|
|
|
|
printchar (buf.buffer[i]);
|
|
|
|
|
|
1993-11-01 22:25:23 +00:00
|
|
|
|
putchar_unfiltered ('\n');
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("%d allocated, %d used.\n", buf.allocated, buf.used);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
|
|
|
|
re_compile_fastmap (&buf);
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("Allowed by fastmap: ");
|
1991-03-28 16:28:29 +00:00
|
|
|
|
for (i = 0; i < (1 << BYTEWIDTH); i++)
|
|
|
|
|
if (fastmap[i]) printchar (i);
|
1993-11-01 22:25:23 +00:00
|
|
|
|
putchar_unfiltered ('\n');
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gets (pat); /* Now read the string to match against */
|
|
|
|
|
|
|
|
|
|
i = re_match (&buf, pat, strlen (pat), 0, 0);
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("Match value %d.\n", i);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NOTDEF
|
|
|
|
|
print_buf (bufp)
|
|
|
|
|
struct re_pattern_buffer *bufp;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("buf is :\n----------------\n");
|
1991-03-28 16:28:29 +00:00
|
|
|
|
for (i = 0; i < bufp->used; i++)
|
|
|
|
|
printchar (bufp->buffer[i]);
|
|
|
|
|
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("Allowed by fastmap: ");
|
1991-03-28 16:28:29 +00:00
|
|
|
|
for (i = 0; i < (1 << BYTEWIDTH); i++)
|
|
|
|
|
if (bufp->fastmap[i])
|
|
|
|
|
printchar (i);
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("\nAllowed by translate: ");
|
1991-03-28 16:28:29 +00:00
|
|
|
|
if (bufp->translate)
|
|
|
|
|
for (i = 0; i < (1 << BYTEWIDTH); i++)
|
|
|
|
|
if (bufp->translate[i])
|
|
|
|
|
printchar (i);
|
1993-11-01 22:25:23 +00:00
|
|
|
|
printf_unfiltered ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
|
|
|
|
|
printf_unfiltered ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
printchar (c)
|
|
|
|
|
char c;
|
|
|
|
|
{
|
|
|
|
|
if (c < 041 || c >= 0177)
|
|
|
|
|
{
|
1993-11-01 22:25:23 +00:00
|
|
|
|
putchar_unfiltered ('\\');
|
|
|
|
|
putchar_unfiltered (((c >> 6) & 3) + '0');
|
|
|
|
|
putchar_unfiltered (((c >> 3) & 7) + '0');
|
|
|
|
|
putchar_unfiltered ((c & 7) + '0');
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1993-11-01 22:25:23 +00:00
|
|
|
|
putchar_unfiltered (c);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error (string)
|
|
|
|
|
char *string;
|
|
|
|
|
{
|
1993-11-01 22:25:23 +00:00
|
|
|
|
puts_unfiltered (string);
|
1991-03-28 16:28:29 +00:00
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* test */
|