GNU Regex 0.12

This commit is contained in:
J.T. Conklin 1993-07-30 20:16:53 +00:00
parent ff5c17099b
commit 6eefa612a9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=218
52 changed files with 28168 additions and 0 deletions

10
gnu/lib/libregex/AUTHORS Normal file
View File

@ -0,0 +1,10 @@
Richard Stallman -- original version and continuing revisions of
regex.c and regex.h, and original version of the documentation.
Karl Berry and Kathryn Hargreaves -- extensive modifications to above,
and all test files.
Jim Blandy -- original version of re_set_registers, revisions to regex.c.
Joe Arceneaux, David MacKenzie, Mike Haertel, Charles Hannum, and
probably others -- revisions to regex.c.

339
gnu/lib/libregex/COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

3030
gnu/lib/libregex/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

117
gnu/lib/libregex/INSTALL Normal file
View File

@ -0,0 +1,117 @@
This is a generic INSTALL file for utilities distributions.
If this package does not come with, e.g., installable documentation or
data files, please ignore the references to them below.
To compile this package:
1. Configure the package for your system. In the directory that this
file is in, type `./configure'. If you're using `csh' on an old
version of System V, you might need to type `sh configure' instead to
prevent `csh' from trying to execute `configure' itself.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation, and
creates the Makefile(s) (one in each subdirectory of the source
directory). In some packages it creates a C header file containing
system-dependent definitions. It also creates a file `config.status'
that you can run in the future to recreate the current configuration.
Running `configure' takes a minute or two. While it is running, it
prints some messages that tell what it is doing. If you don't want to
see the messages, run `configure' with its standard output redirected
to `/dev/null'; for example, `./configure >/dev/null'.
To compile the package in a different directory from the one
containing the source code, you must use a version of `make' that
supports the VPATH variable, such as GNU `make'. `cd' to the directory
where you want the object files and executables to go and run
`configure'. `configure' automatically checks for the source code in
the directory that `configure' is in and in `..'. If for some reason
`configure' is not in the source code directory that you are
configuring, then it will report that it can't find the source code.
In that case, run `configure' with the option `--srcdir=DIR', where
DIR is the directory that contains the source code.
By default, `make install' will install the package's files in
/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify
an installation prefix other than /usr/local by giving `configure' the
option `--prefix=PATH'. Alternately, you can do so by giving a value
for the `prefix' variable when you run `make', e.g.,
make prefix=/usr/gnu
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If
you give `configure' the option `--exec-prefix=PATH' or set the
`make' variable `exec_prefix' to PATH, the package will use PATH as
the prefix for installing programs and libraries. Data files and
documentation will still use the regular prefix. Normally, all files
are installed using the regular prefix.
Another `configure' option is useful mainly in `Makefile' rules for
updating `config.status' and `Makefile'. The `--no-create' option
figures out the configuration for your system and records it in
`config.status', without actually configuring the package (creating
`Makefile's and perhaps a configuration header file). Later, you can
run `./config.status' to actually configure the package. You can also
give `config.status' the `--recheck' option, which makes it re-run
`configure' with the same arguments you used before. This option is
useful if you change `configure'.
Some packages pay attention to `--with-PACKAGE' options to `configure',
where PACKAGE is something like `gnu-libc' or `x' (for the X Window System).
The README should mention any --with- options that the package recognizes.
`configure' ignores any other arguments that you give it.
If your system requires unusual options for compilation or linking
that `configure' doesn't know about, you can give `configure' initial
values for some variables by setting them in the environment. In
Bourne-compatible shells, you can do that on the command line like
this:
CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure
The `make' variables that you might want to override with environment
variables when running `configure' are:
(For these variables, any value given in the environment overrides the
value that `configure' would choose:)
CC C compiler program.
Default is `cc', or `gcc' if `gcc' is in your PATH.
INSTALL Program to use to install files.
Default is `install' if you have it, `cp' otherwise.
(For these variables, any value given in the environment is added to
the value that `configure' chooses:)
DEFS Configuration options, in the form `-Dfoo -Dbar ...'
Do not use this variable in packages that create a
configuration header file.
LIBS Libraries to link with, in the form `-lfoo -lbar ...'
If you need to do unusual things to compile the package, we encourage
you to figure out how `configure' could check whether to do them, and
mail diffs or instructions to the address given in the README so we
can include them in the next release.
2. Type `make' to compile the package. If you want, you can override
the `make' variables CFLAGS and LDFLAGS like this:
make CFLAGS=-O2 LDFLAGS=-s
3. If the package comes with self-tests and you want to run them,
type `make check'. If you're not sure whether there are any, try it;
if `make' responds with something like
make: *** No way to make target `check'. Stop.
then the package does not come with self-tests.
4. Type `make install' to install programs, data files, and
documentation.
5. You can remove the program binaries and object files from the
source directory by typing `make clean'. To also remove the
Makefile(s), the header file containing system-dependent definitions
(if the package uses one), and `config.status' (all the files that
`configure' created), type `make distclean'.
The file `configure.in' is used as a template to create `configure' by
a program called `autoconf'. You will only need it if you want to
regenerate `configure' using a newer version of `autoconf'.

12
gnu/lib/libregex/Makefile Normal file
View File

@ -0,0 +1,12 @@
# $Header: /b/source/CVS/src/gnu/lib/libregex/Makefile,v 1.2 1993/04/10 15:24:44 cgd Exp $
LIB= gnuregex
CFLAGS+=-DHAVE_STRING_H=1
SRCS= regex.c
NOMAN= noman
afterinstall:
install -c -o root -g wheel -m 444 ${.CURDIR}/regex.h \
${DESTDIR}/usr/include
.include <bsd.lib.mk>

View File

@ -0,0 +1,99 @@
# Generated automatically from Makefile.in by configure.
# Makefile for regex.
#
# Copyright (C) 1992, 1993 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
version = 0.12
# You can define CPPFLAGS on the command line. Aside from system-specific
# flags, you can define:
# -DREGEX_MALLOC to use malloc/realloc/free instead of alloca.
# -DDEBUG to enable the compiled pattern disassembler and execution
# tracing; code runs substantially slower.
# -DEXTRACT_MACROS to use the macros EXTRACT_* (as opposed to
# the corresponding C procedures). If not -DDEBUG, the macros
# are used.
CPPFLAGS =
# Likewise, you can override CFLAGS to optimize, use -Wall, etc.
CFLAGS = -g
# Ditto for LDFLAGS and LOADLIBES.
LDFLAGS =
LOADLIBES =
srcdir = .
VPATH = .
CC = gcc
DEFS = -DHAVE_STRING_H=1
SHELL = /bin/sh
subdirs = doc test
default all:: regex.o
.PHONY: default all
regex.o: regex.c regex.h
$(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -c $<
clean mostlyclean::
rm -f *.o
distclean:: clean
rm -f Makefile config.status
extraclean:: distclean
rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
configure: configure.in
autoconf
config.status: configure
sh configure --no-create
Makefile: Makefile.in config.status
sh config.status
makeargs = $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CC='$(CC)' \
DEFS='$(DEFS)' LDFLAGS='$(LDFLAGS)' LOADLIBES='$(LOADLIBES)'
default all install \
mostlyclean clean distclean extraclean realclean \
TAGS check::
for d in $(subdirs); do (cd $$d; $(MAKE) $(makeargs) $@); done
.PHONY: install mostlyclean clean distclean extraclean realclean TAGS check
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
distfiles = AUTHORS ChangeLog COPYING INSTALL NEWS README \
*.in configure regex.c regex.h
distdir = regex-$(version)
distargs = version=$(version) distdir=../$(distdir)/$$d
dist: TAGS configure
@echo "Version numbers in: Makefile.in, ChangeLog, NEWS,"
@echo " regex.c, regex.h,"
@echo " and doc/xregex.texi (if modified)."
rm -rf $(distdir)
mkdir $(distdir)
ln $(distfiles) $(distdir)
for d in $(subdirs); do (cd $$d; $(MAKE) $(distargs) dist); done
tar czhf $(distdir).tar.Z $(distdir)
rm -rf $(distdir)
.PHONY: dist

View File

@ -0,0 +1,98 @@
# Makefile for regex.
#
# Copyright (C) 1992, 1993 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
version = 0.12
# You can define CPPFLAGS on the command line. Aside from system-specific
# flags, you can define:
# -DREGEX_MALLOC to use malloc/realloc/free instead of alloca.
# -DDEBUG to enable the compiled pattern disassembler and execution
# tracing; code runs substantially slower.
# -DEXTRACT_MACROS to use the macros EXTRACT_* (as opposed to
# the corresponding C procedures). If not -DDEBUG, the macros
# are used.
CPPFLAGS =
# Likewise, you can override CFLAGS to optimize, use -Wall, etc.
CFLAGS = -g
# Ditto for LDFLAGS and LOADLIBES.
LDFLAGS =
LOADLIBES =
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
DEFS = @DEFS@
SHELL = /bin/sh
subdirs = doc test
default all:: regex.o
.PHONY: default all
regex.o: regex.c regex.h
$(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -c $<
clean mostlyclean::
rm -f *.o
distclean:: clean
rm -f Makefile config.status
extraclean:: distclean
rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
configure: configure.in
autoconf
config.status: configure
sh configure --no-create
Makefile: Makefile.in config.status
sh config.status
makeargs = $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CC='$(CC)' \
DEFS='$(DEFS)' LDFLAGS='$(LDFLAGS)' LOADLIBES='$(LOADLIBES)'
default all install \
mostlyclean clean distclean extraclean realclean \
TAGS check::
for d in $(subdirs); do (cd $$d; $(MAKE) $(makeargs) $@); done
.PHONY: install mostlyclean clean distclean extraclean realclean TAGS check
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
distfiles = AUTHORS ChangeLog COPYING INSTALL NEWS README \
*.in configure regex.c regex.h
distdir = regex-$(version)
distargs = version=$(version) distdir=../$(distdir)/$$d
dist: TAGS configure
@echo "Version numbers in: Makefile.in, ChangeLog, NEWS,"
@echo " regex.c, regex.h,"
@echo " and doc/xregex.texi (if modified)."
rm -rf $(distdir)
mkdir $(distdir)
ln $(distfiles) $(distdir)
for d in $(subdirs); do (cd $$d; $(MAKE) $(distargs) dist); done
tar czhf $(distdir).tar.Z $(distdir)
rm -rf $(distdir)
.PHONY: dist

62
gnu/lib/libregex/NEWS Normal file
View File

@ -0,0 +1,62 @@
Version 0.12
* regex.c does not #define bcmp/bcopy/bzero if they already are.
* regex.h does not redefine `const' if it is already defined, even if
__STDC__ is not defined.
* RE_SYNTAX_ED added (same as POSIX BRE's).
* The following bugs have been fixed, among others:
* The pattern \w+ doesn't infinite loop.
* The pattern ".+\n" is compiled correctly.
* Expressions with more than MAX_REGNUM groups are compiled correctly.
* Patterns that end in a repetition operator (e.g., `*') match
slightly faster if no looping is actually necessary.
Version 0.11 (17 Sep 92)
* Back-references to nonexistent subexpressions, as in the r.e. `abc\1',
are always invalid. Previously, they could match the literal digit,
e.g., the stated r.e. might have matched `abc1'.
* Empty subexpressions are always valid (POSIX leaves this undefined).
* Simplified rules for ^ and $ being anchors.
* One minor speedup (rewriting the C procedure `pop_failure_point' as a
macro again).
* Bug fixes involving:
- Declarations in regex.h and non-ANSI compilers.
- Bracket expressions with characters between 0x80-0xff.
- Memory leak in re_match_2 on systems requiring `alloca (0)' to
free alloca'd storage.
* Test and documentation files moved into subdirectories.
Version 0.10 (9 Sep 92)
* `obscure_syntax' is now called `re_default_syntax'.
* `re_comp's return type is no longer `const', for compatibility with BSD.
* POSIX syntaxes now include as much functionality as possible
(consistent with the standard).
* Compilation conditionals normalized to what the rest of GNU is
migrating towards these days.
* Bug fixes involving:
- Ranges with characters between 0x80 and 0xff, e.g., [\001-\377].
- `re_compile_fastmap' and the sequence `.*\n'.
- Intervals with exact counts, e.g., a{5}.
* Changed distribution to use a standard Makefile, install the info
files, use a configure script, etc.
Version 0.9
* The longest match was not always chosen: `a*|ab' didn't match `aab'.

60
gnu/lib/libregex/README Normal file
View File

@ -0,0 +1,60 @@
This directory contains the GNU regex library. It is compliant with
POSIX.2, except for internationalization features.
See the file NEWS for a list of major changes in the current release.
See the file INSTALL for compilation instructions. (The only thing
installed is the documentation; regex.c is compiled into regex.o, but
not installed anywhere.)
The subdirectory `doc' contains a (programmers') manual for the library.
It's probably out-of-date. Improvements are welcome.
The subdirectory `test' contains the various tests we've written.
We know this code is not as fast as it might be. If you have specific
suggestions, profiling results, or other such useful information to
report, please do.
Emacs 18 is not going use this revised regex (but Emacs 19 will). If
you want to try it with Emacs 18, apply the patch at the end of this
file first.
Mail bug reports to bug-gnu-utils@prep.ai.mit.edu.
Please include an actual regular expression that fails (and the syntax
used to compile it); without that, there's no way to reproduce the bug,
so there's no way we can fix it. Even if you include a patch, also
include the regular expression in error; otherwise, we can't know for
sure what you're trying to fix.
Here is the patch to make this version of regex work with Emacs 18.
*** ORIG/search.c Tue Jan 8 13:04:55 1991
--- search.c Sun Jan 5 10:57:00 1992
***************
*** 25,26 ****
--- 25,28 ----
#include "commands.h"
+
+ #include <sys/types.h>
#include "regex.h"
***************
*** 477,479 ****
/* really needed. */
! && *(searchbuf.buffer) == (char) exactn /* first item is "exact match" */
&& searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
--- 479,482 ----
/* really needed. */
! /* first item is "exact match" */
! && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE
&& searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
***************
*** 1273,1275 ****
searchbuf.allocated = 100;
! searchbuf.buffer = (char *) malloc (searchbuf.allocated);
searchbuf.fastmap = search_fastmap;
--- 1276,1278 ----
searchbuf.allocated = 100;
! searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated);
searchbuf.fastmap = search_fastmap;

3
gnu/lib/libregex/VERSION Normal file
View File

@ -0,0 +1,3 @@
GNU regex version 0.12
complete, unmodified regex sources are available from prep.ai.mit.edu.

View File

@ -0,0 +1,59 @@
#!/bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host sun-lamp.cs.berkeley.edu:
#
# configure
for arg
do
case "$arg" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
exec /bin/sh configure ;;
*) echo "Usage: config.status --recheck" 2>&1; exit 1 ;;
esac
done
trap 'rm -f Makefile doc/Makefile test/Makefile; exit 1' 1 3 15
CC='gcc'
INSTALL='/usr/bin/install -c'
INSTALL_PROGRAM='$(INSTALL)'
INSTALL_DATA='$(INSTALL) -m 644'
CPP='${CC-cc} -E'
ALLOCA=''
LIBS=''
srcdir='.'
DEFS=' -DHAVE_STRING_H=1'
prefix='/usr'
exec_prefix='${prefix}'
prsub='s%^prefix\([ ]*\)=\([ ]*\).*$%prefix\1=\2/usr%
s%^exec_prefix\([ ]*\)=\([ ]*\).*$%exec_prefix\1=\2${prefix}%'
top_srcdir=$srcdir
for file in .. Makefile doc/Makefile test/Makefile; do if [ "x$file" != "x.." ]; then
srcdir=$top_srcdir
# Remove last slash and all that follows it. Not all systems have dirname.
dir=`echo $file|sed 's%/[^/][^/]*$%%'`
if test "$dir" != "$file"; then
test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
test ! -d $dir && mkdir $dir
fi
echo creating $file
rm -f $file
echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file
sed -e "
$prsub
s%@CC@%$CC%g
s%@INSTALL@%$INSTALL%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@CPP@%$CPP%g
s%@ALLOCA@%$ALLOCA%g
s%@LIBS@%$LIBS%g
s%@srcdir@%$srcdir%g
s%@DEFS@%$DEFS%
" $top_srcdir/${file}.in >> $file
fi; done
exit 0

462
gnu/lib/libregex/configure vendored Normal file
View File

@ -0,0 +1,462 @@
#!/bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf.
# Copyright (C) 1991, 1992, 1993 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create]
# [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET]
# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and
# --with-PACKAGE unless this script has special code to handle it.
for arg
do
# Handle --exec-prefix with a space before the argument.
if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix=
# Handle --host with a space before the argument.
elif test x$next_host = xyes; then next_host=
# Handle --prefix with a space before the argument.
elif test x$next_prefix = xyes; then prefix=$arg; next_prefix=
# Handle --srcdir with a space before the argument.
elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir=
else
case $arg in
# For backward compatibility, also recognize exact --exec_prefix.
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*)
exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e)
next_exec_prefix=yes ;;
-gas | --gas | --ga | --g) ;;
-host=* | --host=* | --hos=* | --ho=* | --h=*) ;;
-host | --host | --hos | --ho | --h)
next_host=yes ;;
-nfp | --nfp | --nf) ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no)
no_create=1 ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
next_prefix=yes ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*)
srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s)
next_srcdir=yes ;;
-with-* | --with-*)
package=`echo $arg|sed 's/-*with-//'`
# Delete all the valid chars; see if any are left.
if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then
echo "configure: $package: invalid package name" >&2; exit 1
fi
eval "with_`echo $package|sed s/-/_/g`=1" ;;
*) ;;
esac
fi
done
trap 'rm -f conftest* core; exit 1' 1 3 15
rm -f conftest*
compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
unique_file=regex.c
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
srcdirdefaulted=yes
# Try the directory containing this script, then `..'.
prog=$0
confdir=`echo $prog|sed 's%/[^/][^/]*$%%'`
test "X$confdir" = "X$prog" && confdir=.
srcdir=$confdir
if test ! -r $srcdir/$unique_file; then
srcdir=..
fi
fi
if test ! -r $srcdir/$unique_file; then
if test x$srcdirdefaulted = xyes; then
echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2
else
echo "configure: Can not find sources in \`${srcdir}'." 1>&2
fi
exit 1
fi
# Preserve a srcdir of `.' to avoid automounter screwups with pwd.
# But we can't avoid them for `..', to make subdirectories work.
case $srcdir in
.|/*|~*) ;;
*) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute.
esac
if test -z "$CC"; then
echo checking for gcc
saveifs="$IFS"; IFS="${IFS}:"
for dir in $PATH; do
test -z "$dir" && dir=.
if test -f $dir/gcc; then
CC="gcc"
break
fi
done
IFS="$saveifs"
fi
test -z "$CC" && CC="cc"
# Find out if we are using GNU C, under whatever name.
cat > conftest.c <<EOF
#ifdef __GNUC__
yes
#endif
EOF
${CC-cc} -E conftest.c > conftest.out 2>&1
if egrep yes conftest.out >/dev/null 2>&1; then
GCC=1 # For later tests.
fi
rm -f conftest*
# Make sure to not get the incompatible SysV /etc/install and
# /usr/sbin/install, which might be in PATH before a BSD-like install,
# or the SunOS /usr/etc/install directory, or the AIX /bin/install,
# or the AFS install, which mishandles nonexistent args. (Sigh.)
if test -z "$INSTALL"; then
echo checking for install
saveifs="$IFS"; IFS="${IFS}:"
for dir in $PATH; do
test -z "$dir" && dir=.
case $dir in
/etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;;
*)
if test -f $dir/install; then
if grep dspmsg $dir/install >/dev/null 2>&1; then
: # AIX
else
INSTALL="$dir/install -c"
INSTALL_PROGRAM='$(INSTALL)'
INSTALL_DATA='$(INSTALL) -m 644'
break
fi
fi
;;
esac
done
IFS="$saveifs"
fi
INSTALL=${INSTALL-cp}
INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'}
INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'}
echo checking for AIX
echo checking how to run the C preprocessor
if test -z "$CPP"; then
CPP='${CC-cc} -E'
cat > conftest.c <<EOF
#include <stdio.h>
EOF
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
if test -z "$err"; then
:
else
CPP=/lib/cpp
fi
rm -f conftest*
fi
cat > conftest.c <<EOF
#ifdef _AIX
yes
#endif
EOF
eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
if egrep "yes" conftest.out >/dev/null 2>&1; then
DEFS="$DEFS -D_ALL_SOURCE=1"
fi
rm -f conftest*
echo checking for DYNIX/ptx libseq
cat > conftest.c <<EOF
#if defined(_SEQUENT_)
yes
#endif
EOF
eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
if egrep "yes" conftest.out >/dev/null 2>&1; then
SEQUENT=1
fi
rm -f conftest*
test -n "$SEQUENT" && test -f /usr/lib/libseq.a &&
LIBS="$LIBS -lseq"
echo checking for POSIXized ISC
if test -d /etc/conf/kconfig.d &&
grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
then
ISC=1 # If later tests want to check for ISC.
DEFS="$DEFS -D_POSIX_SOURCE=1"
if test -n "$GCC"; then
CC="$CC -posix"
else
CC="$CC -Xp"
fi
fi
echo checking for minix/config.h
cat > conftest.c <<EOF
#include <minix/config.h>
EOF
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
if test -z "$err"; then
MINIX=1
fi
rm -f conftest*
# The Minix shell can't assign to the same variable on the same line!
if test -n "$MINIX"; then
DEFS="$DEFS -D_POSIX_SOURCE=1"
DEFS="$DEFS -D_POSIX_1_SOURCE=2"
DEFS="$DEFS -D_MINIX=1"
fi
echo checking for ANSI C header files
cat > conftest.c <<EOF
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
EOF
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
if test -z "$err"; then
# SunOS string.h does not declare mem*, contrary to ANSI.
echo '#include <string.h>' > conftest.c
eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
if egrep "memchr" conftest.out >/dev/null 2>&1; then
# SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
cat > conftest.c <<EOF
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#define XOR(e,f) (((e) && !(f)) || (!(e) && (f)))
int main () { int i; for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
eval $compile
if test -s conftest && (./conftest; exit) 2>/dev/null; then
DEFS="$DEFS -DSTDC_HEADERS=1"
fi
rm -f conftest*
fi
rm -f conftest*
fi
rm -f conftest*
for hdr in string.h
do
trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'`
echo checking for ${hdr}
cat > conftest.c <<EOF
#include <${hdr}>
EOF
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
if test -z "$err"; then
DEFS="$DEFS -D${trhdr}=1"
fi
rm -f conftest*
done
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless!
echo checking for working alloca.h
cat > conftest.c <<EOF
#include <alloca.h>
main() { exit(0); }
t() { char *p = alloca(2 * sizeof(int)); }
EOF
if eval $compile; then
DEFS="$DEFS -DHAVE_ALLOCA_H=1"
fi
rm -f conftest*
decl="#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#if HAVE_ALLOCA_H
#include <alloca.h>
#else
#ifdef _AIX
#pragma alloca
#else
char *alloca ();
#endif
#endif
#endif
"
echo checking for alloca
cat > conftest.c <<EOF
$decl
main() { exit(0); }
t() { char *p = (char *) alloca(1); }
EOF
if eval $compile; then
:
else
alloca_missing=1
fi
rm -f conftest*
if test -n "$alloca_missing"; then
# The SVR3 libPW and SVR4 libucb both contain incompatible functions
# that cause trouble. Some versions do not even contain alloca or
# contain a buggy version. If you still want to use their alloca,
# use ar to extract alloca.o from them instead of compiling alloca.c.
ALLOCA=alloca.o
fi
prog='/* Ultrix mips cc rejects this. */
typedef int charset[2]; const charset x;
/* SunOS 4.1.1 cc rejects this. */
char const *const *p;
char **p2;
/* HPUX 7.0 cc rejects these. */
++p;
p2 = (char const* const*) p;'
echo checking for working const
cat > conftest.c <<EOF
main() { exit(0); }
t() { $prog }
EOF
if eval $compile; then
:
else
DEFS="$DEFS -Dconst="
fi
rm -f conftest*
if test -z "$prefix"
then
echo checking for gcc to derive installation directory prefix
saveifs="$IFS"; IFS="$IFS:"
for dir in $PATH; do
test -z "$dir" && dir=.
if test $dir != . && test -f $dir/gcc; then
# Not all systems have dirname.
prefix=`echo $dir|sed 's%/[^/][^/]*$%%'`
break
fi
done
IFS="$saveifs"
fi
if test -n "$prefix"; then
test -z "$exec_prefix" && exec_prefix='${prefix}'
prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%"
fi
if test -n "$exec_prefix"; then
prsub="$prsub
s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\
exec_prefix\\1=\\2$exec_prefix%"
fi
trap 'rm -f config.status; exit 1' 1 3 15
echo creating config.status
rm -f config.status
cat > config.status <<EOF
#!/bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null`:
#
# $0 $*
for arg
do
case "\$arg" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
exec /bin/sh $0 $* ;;
*) echo "Usage: config.status --recheck" 2>&1; exit 1 ;;
esac
done
trap 'rm -f Makefile doc/Makefile test/Makefile; exit 1' 1 3 15
CC='$CC'
INSTALL='$INSTALL'
INSTALL_PROGRAM='$INSTALL_PROGRAM'
INSTALL_DATA='$INSTALL_DATA'
CPP='$CPP'
ALLOCA='$ALLOCA'
LIBS='$LIBS'
srcdir='$srcdir'
DEFS='$DEFS'
prefix='$prefix'
exec_prefix='$exec_prefix'
prsub='$prsub'
EOF
cat >> config.status <<\EOF
top_srcdir=$srcdir
for file in .. Makefile doc/Makefile test/Makefile; do if [ "x$file" != "x.." ]; then
srcdir=$top_srcdir
# Remove last slash and all that follows it. Not all systems have dirname.
dir=`echo $file|sed 's%/[^/][^/]*$%%'`
if test "$dir" != "$file"; then
test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
test ! -d $dir && mkdir $dir
fi
echo creating $file
rm -f $file
echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file
sed -e "
$prsub
s%@CC@%$CC%g
s%@INSTALL@%$INSTALL%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@CPP@%$CPP%g
s%@ALLOCA@%$ALLOCA%g
s%@LIBS@%$LIBS%g
s%@srcdir@%$srcdir%g
s%@DEFS@%$DEFS%
" $top_srcdir/${file}.in >> $file
fi; done
exit 0
EOF
chmod +x config.status
test -n "$no_create" || ./config.status

View File

@ -0,0 +1,23 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(regex.c)
AC_PROG_CC
AC_PROG_INSTALL
dnl I'm not sure if AC_AIX and AC_DYNIX_SEQ are really necessary. The
dnl Autoconf documentation isn't specific about which BSD functions they
dnl provide.
AC_AIX
AC_DYNIX_SEQ
AC_ISC_POSIX
AC_MINIX
AC_STDC_HEADERS
AC_HAVE_HEADERS(string.h)
AC_ALLOCA
AC_CONST
AC_PREFIX(gcc)
AC_OUTPUT(Makefile doc/Makefile test/Makefile)

View File

@ -0,0 +1,93 @@
# Generated automatically from Makefile.in by configure.
# Makefile for regex documentation.
#
# Copyright (C) 1992 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Installation directories.
prefix = /usr
infodir = $(prefix)/info
srcdir = .
VPATH = .:../.
INSTALL = /usr/bin/install -c
INSTALL_DATA = $(INSTALL) -m 644
MAKEINFO = makeinfo --no-split
SHELL = /bin/sh
TEX = tex
TEXINDEX = texindex
default all: regex.info regex.dvi
.PHONY: default all
# We need to include some code from regex.h.
regex.texi: xregex.texi
rm -f $@
gawk -f include.awk -vsource=../$(srcdir)/regex.h \
<../$(srcdir)/doc/xregex.texi \
| expand >$@
chmod a-w $@
regex.dvi: regex.cps
$(TEX) regex.texi
regex.cps: regex.cp
$(TEXINDEX) regex.??
regex.cp: regex.texi
$(TEX) ../$(srcdir)/doc/regex.texi
regex.info: regex.texi
$(MAKEINFO) ../$(srcdir)/doc/regex.texi
# I know of no way to make a good TAGS file from Texinfo source.
TAGS:
check:
.PHONY: check
install: regex.info
-mkdir $(prefix) $(infodir)
for i in *.info*; do $(INSTALL_DATA) $$i $(infodir)/$$i; done
.PHONY: install
clean mostlyclean:
rm -f regex.?? *.dvi *.log *.toc
distclean: clean
rm -f Makefile
for f in regex.??s; do if test -z "`cat $$f`"; then rm -f $$f; fi; done
realclean: distclean
rm -f *.info* regex.??? regex.texi TAGS
extraclean: distclean
rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
.PHONY: mostlyclean clean distclean realclean extraclean
Makefile: Makefile.in ../config.status
(cd ..; sh config.status)
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
# Assumes $(distdir) is the place to put our files.
distfiles = Makefile.in *.texi texinfo.tex include.awk \
regex.info* regex.aux regex.cps
dist: Makefile regex.info regex.cps
mkdir $(distdir)
ln $(distfiles) $(distdir)
.PHONY: dist

View File

@ -0,0 +1,92 @@
# Makefile for regex documentation.
#
# Copyright (C) 1992 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Installation directories.
prefix = /usr/local
infodir = $(prefix)/info
srcdir = @srcdir@
VPATH = @srcdir@:../@srcdir@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
MAKEINFO = makeinfo --no-split
SHELL = /bin/sh
TEX = tex
TEXINDEX = texindex
default all: regex.info regex.dvi
.PHONY: default all
# We need to include some code from regex.h.
regex.texi: xregex.texi
rm -f $@
gawk -f include.awk -vsource=../$(srcdir)/regex.h \
<../$(srcdir)/doc/xregex.texi \
| expand >$@
chmod a-w $@
regex.dvi: regex.cps
$(TEX) regex.texi
regex.cps: regex.cp
$(TEXINDEX) regex.??
regex.cp: regex.texi
$(TEX) ../$(srcdir)/doc/regex.texi
regex.info: regex.texi
$(MAKEINFO) ../$(srcdir)/doc/regex.texi
# I know of no way to make a good TAGS file from Texinfo source.
TAGS:
check:
.PHONY: check
install: regex.info
-mkdir $(prefix) $(infodir)
for i in *.info*; do $(INSTALL_DATA) $$i $(infodir)/$$i; done
.PHONY: install
clean mostlyclean:
rm -f regex.?? *.dvi *.log *.toc
distclean: clean
rm -f Makefile
for f in regex.??s; do if test -z "`cat $$f`"; then rm -f $$f; fi; done
realclean: distclean
rm -f *.info* regex.??? regex.texi TAGS
extraclean: distclean
rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
.PHONY: mostlyclean clean distclean realclean extraclean
Makefile: Makefile.in ../config.status
(cd ..; sh config.status)
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
# Assumes $(distdir) is the place to put our files.
distfiles = Makefile.in *.texi texinfo.tex include.awk \
regex.info* regex.aux regex.cps
dist: Makefile regex.info regex.cps
mkdir $(distdir)
ln $(distfiles) $(distdir)
.PHONY: dist

View File

@ -0,0 +1,19 @@
# Assume `source' is set with -vsource=filename on the command line.
#
/^\[\[\[/ { inclusion = $2; # name of the thing to include.
printing = 0;
while ((getline line < source) > 0)
{
if (match (line, "\\[\\[\\[end " inclusion "\\]\\]\\]"))
printing = 0;
if (printing)
print line;
if (match (line,"\\[\\[\\[begin " inclusion "\\]\\]\\]"))
printing = 1;
}
close (source);
next;
}
{ print }

View File

@ -0,0 +1,136 @@
'xrdef {Overview-pg}{1}
'xrdef {Overview-snt}{Chapter'tie1}
'xrdef {Regular Expression Syntax-pg}{2}
'xrdef {Regular Expression Syntax-snt}{Chapter'tie2}
'xrdef {Syntax Bits-pg}{2}
'xrdef {Syntax Bits-snt}{Section'tie2.1}
'xrdef {Predefined Syntaxes-pg}{5}
'xrdef {Predefined Syntaxes-snt}{Section'tie2.2}
'xrdef {Collating Elements vs. Characters-pg}{6}
'xrdef {Collating Elements vs. Characters-snt}{Section'tie2.3}
'xrdef {The Backslash Character-pg}{7}
'xrdef {The Backslash Character-snt}{Section'tie2.4}
'xrdef {Common Operators-pg}{9}
'xrdef {Common Operators-snt}{Chapter'tie3}
'xrdef {Match-self Operator-pg}{9}
'xrdef {Match-self Operator-snt}{Section'tie3.1}
'xrdef {Match-any-character Operator-pg}{9}
'xrdef {Match-any-character Operator-snt}{Section'tie3.2}
'xrdef {Concatenation Operator-pg}{10}
'xrdef {Concatenation Operator-snt}{Section'tie3.3}
'xrdef {Repetition Operators-pg}{10}
'xrdef {Repetition Operators-snt}{Section'tie3.4}
'xrdef {Match-zero-or-more Operator-pg}{10}
'xrdef {Match-zero-or-more Operator-snt}{Section'tie3.4.1}
'xrdef {Match-one-or-more Operator-pg}{11}
'xrdef {Match-one-or-more Operator-snt}{Section'tie3.4.2}
'xrdef {Match-zero-or-one Operator-pg}{11}
'xrdef {Match-zero-or-one Operator-snt}{Section'tie3.4.3}
'xrdef {Interval Operators-pg}{12}
'xrdef {Interval Operators-snt}{Section'tie3.4.4}
'xrdef {Alternation Operator-pg}{13}
'xrdef {Alternation Operator-snt}{Section'tie3.5}
'xrdef {List Operators-pg}{13}
'xrdef {List Operators-snt}{Section'tie3.6}
'xrdef {Character Class Operators-pg}{14}
'xrdef {Character Class Operators-snt}{Section'tie3.6.1}
'xrdef {Range Operator-pg}{15}
'xrdef {Range Operator-snt}{Section'tie3.6.2}
'xrdef {Grouping Operators-pg}{16}
'xrdef {Grouping Operators-snt}{Section'tie3.7}
'xrdef {Back-reference Operator-pg}{17}
'xrdef {Back-reference Operator-snt}{Section'tie3.8}
'xrdef {Anchoring Operators-pg}{18}
'xrdef {Anchoring Operators-snt}{Section'tie3.9}
'xrdef {Match-beginning-of-line Operator-pg}{18}
'xrdef {Match-beginning-of-line Operator-snt}{Section'tie3.9.1}
'xrdef {Match-end-of-line Operator-pg}{18}
'xrdef {Match-end-of-line Operator-snt}{Section'tie3.9.2}
'xrdef {GNU Operators-pg}{20}
'xrdef {GNU Operators-snt}{Chapter'tie4}
'xrdef {Word Operators-pg}{20}
'xrdef {Word Operators-snt}{Section'tie4.1}
'xrdef {Non-Emacs Syntax Tables-pg}{20}
'xrdef {Non-Emacs Syntax Tables-snt}{Section'tie4.1.1}
'xrdef {Match-word-boundary Operator-pg}{20}
'xrdef {Match-word-boundary Operator-snt}{Section'tie4.1.2}
'xrdef {Match-within-word Operator-pg}{20}
'xrdef {Match-within-word Operator-snt}{Section'tie4.1.3}
'xrdef {Match-beginning-of-word Operator-pg}{21}
'xrdef {Match-beginning-of-word Operator-snt}{Section'tie4.1.4}
'xrdef {Match-end-of-word Operator-pg}{21}
'xrdef {Match-end-of-word Operator-snt}{Section'tie4.1.5}
'xrdef {Match-word-constituent Operator-pg}{21}
'xrdef {Match-word-constituent Operator-snt}{Section'tie4.1.6}
'xrdef {Match-non-word-constituent Operator-pg}{21}
'xrdef {Match-non-word-constituent Operator-snt}{Section'tie4.1.7}
'xrdef {Buffer Operators-pg}{21}
'xrdef {Buffer Operators-snt}{Section'tie4.2}
'xrdef {Match-beginning-of-buffer Operator-pg}{21}
'xrdef {Match-beginning-of-buffer Operator-snt}{Section'tie4.2.1}
'xrdef {Match-end-of-buffer Operator-pg}{21}
'xrdef {Match-end-of-buffer Operator-snt}{Section'tie4.2.2}
'xrdef {GNU Emacs Operators-pg}{22}
'xrdef {GNU Emacs Operators-snt}{Chapter'tie5}
'xrdef {Syntactic Class Operators-pg}{22}
'xrdef {Syntactic Class Operators-snt}{Section'tie5.1}
'xrdef {Emacs Syntax Tables-pg}{22}
'xrdef {Emacs Syntax Tables-snt}{Section'tie5.1.1}
'xrdef {Match-syntactic-class Operator-pg}{22}
'xrdef {Match-syntactic-class Operator-snt}{Section'tie5.1.2}
'xrdef {Match-not-syntactic-class Operator-pg}{22}
'xrdef {Match-not-syntactic-class Operator-snt}{Section'tie5.1.3}
'xrdef {What Gets Matched?-pg}{23}
'xrdef {What Gets Matched?-snt}{Chapter'tie6}
'xrdef {Programming with Regex-pg}{24}
'xrdef {Programming with Regex-snt}{Chapter'tie7}
'xrdef {GNU Regex Functions-pg}{24}
'xrdef {GNU Regex Functions-snt}{Section'tie7.1}
'xrdef {GNU Pattern Buffers-pg}{24}
'xrdef {GNU Pattern Buffers-snt}{Section'tie7.1.1}
'xrdef {GNU Regular Expression Compiling-pg}{26}
'xrdef {GNU Regular Expression Compiling-snt}{Section'tie7.1.2}
'xrdef {GNU Matching-pg}{27}
'xrdef {GNU Matching-snt}{Section'tie7.1.3}
'xrdef {GNU Searching-pg}{28}
'xrdef {GNU Searching-snt}{Section'tie7.1.4}
'xrdef {Matching/Searching with Split Data-pg}{29}
'xrdef {Matching/Searching with Split Data-snt}{Section'tie7.1.5}
'xrdef {Searching with Fastmaps-pg}{30}
'xrdef {Searching with Fastmaps-snt}{Section'tie7.1.6}
'xrdef {GNU Translate Tables-pg}{31}
'xrdef {GNU Translate Tables-snt}{Section'tie7.1.7}
'xrdef {Using Registers-pg}{32}
'xrdef {Using Registers-snt}{Section'tie7.1.8}
'xrdef {Freeing GNU Pattern Buffers-pg}{34}
'xrdef {Freeing GNU Pattern Buffers-snt}{Section'tie7.1.9}
'xrdef {POSIX Regex Functions-pg}{35}
'xrdef {POSIX Regex Functions-snt}{Section'tie7.2}
'xrdef {POSIX Pattern Buffers-pg}{35}
'xrdef {POSIX Pattern Buffers-snt}{Section'tie7.2.1}
'xrdef {POSIX Regular Expression Compiling-pg}{35}
'xrdef {POSIX Regular Expression Compiling-snt}{Section'tie7.2.2}
'xrdef {POSIX Matching-pg}{37}
'xrdef {POSIX Matching-snt}{Section'tie7.2.3}
'xrdef {Reporting Errors-pg}{38}
'xrdef {Reporting Errors-snt}{Section'tie7.2.4}
'xrdef {Using Byte Offsets-pg}{39}
'xrdef {Using Byte Offsets-snt}{Section'tie7.2.5}
'xrdef {Freeing POSIX Pattern Buffers-pg}{39}
'xrdef {Freeing POSIX Pattern Buffers-snt}{Section'tie7.2.6}
'xrdef {BSD Regex Functions-pg}{40}
'xrdef {BSD Regex Functions-snt}{Section'tie7.3}
'xrdef {BSD Regular Expression Compiling-pg}{40}
'xrdef {BSD Regular Expression Compiling-snt}{Section'tie7.3.1}
'xrdef {BSD Searching-pg}{40}
'xrdef {BSD Searching-snt}{Section'tie7.3.2}
'xrdef {Copying-pg}{42}
'xrdef {Copying-snt}{Appendix'tie'char65{}}
'xrdef {Copying-pg}{42}
'xrdef {Copying-snt}{}
'xrdef {Copying-pg}{43}
'xrdef {Copying-snt}{}
'xrdef {Copying-pg}{48}
'xrdef {Copying-snt}{}
'xrdef {Index-pg}{50}
'xrdef {Index-snt}{}

View File

@ -0,0 +1,152 @@
\initial {$}
\entry {\code {$}}{18}
\initial {(}
\entry {\code {(}}{16}
\initial {)}
\entry {\code {)}}{16}
\initial {*}
\entry {\samp {*}}{10}
\initial {-}
\entry {\samp {-}}{13}
\initial {.}
\entry {\samp {.}}{9}
\initial {:}
\entry {\samp {:]} in regex}{14}
\initial {?}
\entry {\samp {?}}{11}
\initial {[}
\entry {\samp {[}}{13}
\entry {\samp {[:} in regex}{14}
\entry {\samp {[{\tt\hat}}}{13}
\initial {]}
\entry {\samp {]}}{13}
\initial {{\tt\char'173}}
\entry {\samp {{\tt\char'173}}}{12}
\initial {{\tt\char'174}}
\entry {\code {{\tt\char'174}}}{13}
\initial {{\tt\char'175}}
\entry {\samp {{\tt\char'175}}}{12}
\initial {{\tt\char43}}
\entry {\samp {{\tt\char43}}}{11}
\initial {{\tt\hat}}
\entry {\samp {{\tt\hat}}}{13}
\entry {\code {{\tt\hat}}}{18}
\initial {{\tt\indexbackslash }}
\entry {{\tt\indexbackslash }}{7}
\entry {\samp {{\tt\indexbackslash }}}{13}
\entry {\samp {{\tt\indexbackslash }'}}{21}
\entry {\code {{\tt\indexbackslash }(}}{16}
\entry {\code {{\tt\indexbackslash })}}{16}
\entry {\samp {{\tt\indexbackslash }`}}{21}
\entry {\samp {{\tt\indexbackslash }{\tt\char'173}}}{12}
\entry {\code {{\tt\indexbackslash }{\tt\char'174}}}{13}
\entry {\samp {{\tt\indexbackslash }{\tt\char'175}}}{12}
\entry {\samp {{\tt\indexbackslash }{\tt\gtr}}}{21}
\entry {\samp {{\tt\indexbackslash }{\tt\less}}}{21}
\entry {\samp {{\tt\indexbackslash }b}}{20}
\entry {\samp {{\tt\indexbackslash }B}}{20}
\entry {\samp {{\tt\indexbackslash }s}}{22}
\entry {\samp {{\tt\indexbackslash }S}}{22}
\entry {\samp {{\tt\indexbackslash }w}}{21}
\entry {\samp {{\tt\indexbackslash }W}}{21}
\initial {A}
\entry {\code {allocated \r {initialization}}}{26}
\entry {alternation operator}{13}
\entry {alternation operator and \samp {{\tt\hat}}}{18}
\entry {anchoring}{18}
\entry {anchors}{18}
\entry {Awk}{5}
\initial {B}
\entry {back references}{17}
\entry {backtracking}{10, 13}
\entry {beginning-of-line operator}{18}
\entry {bracket expression}{13}
\entry {\code {buffer \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27}
\entry {\code {buffer \r {initialization}}}{26}
\initial {C}
\entry {character classes}{14}
\initial {E}
\entry {Egrep}{5}
\entry {Emacs}{5}
\entry {end-of-line operator}{18}
\entry {\code {end\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32}
\initial {F}
\entry {\code {fastmap \r {initialization}}}{26}
\entry {\code {fastmap{\_}accurate \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27}
\entry {fastmaps}{30}
\initial {G}
\entry {Grep}{5}
\entry {grouping}{16}
\initial {I}
\entry {ignoring case}{35}
\entry {interval expression}{12}
\initial {M}
\entry {matching list}{13}
\entry {matching newline}{13}
\entry {matching with GNU functions}{27}
\initial {N}
\entry {\code {newline{\_}anchor \r {field in pattern buffer}}}{18}
\entry {nonmatching list}{13}
\entry {\code {not{\_}bol \r {field in pattern buffer}}}{18}
\entry {\code {num_regs\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32}
\initial {O}
\entry {open-group operator and \samp {{\tt\hat}}}{18}
\entry {or operator}{13}
\initial {P}
\entry {parenthesizing}{16}
\entry {pattern buffer initialization}{26}
\entry {pattern buffer, definition of}{24}
\entry {POSIX Awk}{5}
\initial {R}
\entry {\code {range \r {argument to \code {re{\_}search}}}}{28}
\entry {\code {re_registers}}{32}
\entry {\code {RE{\_}BACKSLASH{\_}ESCAPE{\_}IN{\_}LIST}}{3}
\entry {\code {RE{\_}BK{\_}PLUS{\_}QM}}{3}
\entry {\code {RE{\_}CHAR{\_}CLASSES}}{3}
\entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}ANCHORS}}{3}
\entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}ANCHORS \r {(and \samp {{\tt\hat}})}}}{18}
\entry {\code {RE{\_}CONTEXT{\_}INDEP{\_}OPS}}{3}
\entry {\code {RE{\_}CONTEXT{\_}INVALID{\_}OPS}}{3}
\entry {\code {RE{\_}DOT{\_}NEWLINE}}{3}
\entry {\code {RE{\_}DOT{\_}NOT{\_}NULL}}{4}
\entry {\code {RE{\_}INTERVALS}}{4}
\entry {\code {RE{\_}LIMITED{\_}OPS}}{4}
\entry {\code {RE{\_}NEWLINE{\_}ALT}}{4}
\entry {\code {RE{\_}NO{\_}BK{\_}BRACES}}{4}
\entry {\code {RE{\_}NO{\_}BK{\_}PARENS}}{4}
\entry {\code {RE{\_}NO{\_}BK{\_}REFS}}{4}
\entry {\code {RE{\_}NO{\_}BK{\_}VBAR}}{4}
\entry {\code {RE{\_}NO{\_}EMPTY{\_}RANGES}}{4}
\entry {\code {re{\_}nsub \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27}
\entry {\code {re{\_}pattern{\_}buffer \r {definition}}}{24}
\entry {\code {re{\_}syntax{\_}options \r {initialization}}}{26}
\entry {\code {RE{\_}UNMATCHED{\_}RIGHT{\_}PAREN{\_}ORD}}{4}
\entry {\code {REG{\_}EXTENDED}}{35}
\entry {\code {REG{\_}ICASE}}{35}
\entry {\code {REG{\_}NEWLINE}}{36}
\entry {\code {REG{\_}NOSUB}}{35}
\entry {\code {regex.c}}{1}
\entry {\code {regex.h}}{1}
\entry {regexp anchoring}{18}
\entry {\code {regmatch{\_}t}}{39}
\entry {\code {regs{\_}allocated}}{32}
\entry {\code {REGS{\_}FIXED}}{33}
\entry {\code {REGS{\_}REALLOCATE}}{32}
\entry {\code {REGS{\_}UNALLOCATED}}{32}
\entry {regular expressions, syntax of}{2}
\initial {S}
\entry {searching with GNU functions}{28}
\entry {\code {start \r {argument to \code {re{\_}search}}}}{28}
\entry {\code {start\penalty 10000{\spaceskip = 0pt{} }\r {in\penalty 10000{\spaceskip = 0pt{} }\code {struct\penalty 10000{\spaceskip = 0pt{} }re_registers}}}}{32}
\entry {\code {struct re{\_}pattern{\_}buffer \r {definition}}}{24}
\entry {subexpressions}{16}
\entry {syntax bits}{2}
\entry {\code {syntax \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27}
\entry {syntax initialization}{26}
\entry {syntax of regular expressions}{2}
\initial {T}
\entry {\code {translate \r {initialization}}}{26}
\initial {U}
\entry {\code {used \r {field, set by \code {re{\_}compile{\_}pattern}}}}{27}
\initial {W}
\entry {word boundaries, matching}{20}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4948
gnu/lib/libregex/regex.c Normal file

File diff suppressed because it is too large Load Diff

490
gnu/lib/libregex/regex.h Normal file
View File

@ -0,0 +1,490 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 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
the Free Software Foundation; either version 2, 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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#ifdef VMS
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
#include <stddef.h>
#endif
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax
remains the value 0. The bits are given in alphabetical order, and
the definitions shifted by one from the previous bit; thus, when we
add or remove a bit, only one other definition need change. */
typedef unsigned reg_syntax_t;
/* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */
#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
/* If this bit is not set, then + and ? are operators, and \+ and \? are
literals.
If set, then \+ and \? are operators and + and ? are literals. */
#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
/* If this bit is set, then character classes are supported. They are:
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
If not set, then character classes are not supported. */
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
/* If this bit is set, then ^ and $ are always anchors (outside bracket
expressions, of course).
If this bit is not set, then it depends:
^ is an anchor if it is at the beginning of a regular
expression or after an open-group or an alternation operator;
$ is an anchor if it is at the end of a regular expression, or
before a close-group or an alternation operator.
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
POSIX draft 11.2 says that * etc. in leading positions is undefined.
We already implemented a previous draft which made those constructs
invalid, though, so we haven't changed the code back. */
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
immediately after an alternation or begin-group operator. */
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
/* If this bit is set, then . matches newline.
If not set, then it doesn't. */
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
/* If this bit is set, then . doesn't match NUL.
If not set, then it does. */
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
/* If this bit is set, nonmatching lists [^...] do not match newline.
If not set, they do. */
#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
/* If this bit is set, either \{...\} or {...} defines an
interval, depending on RE_NO_BK_BRACES.
If not set, \{, \}, {, and } are literals. */
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
/* If this bit is set, +, ? and | aren't recognized as operators.
If not set, they are. */
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
/* If this bit is set, newline is an alternation operator.
If not set, newline is literal. */
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
are literals.
If not set, then `\{...\}' defines an interval. */
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
/* If this bit is set, (...) defines a group, and \( and \) are literals.
If not set, \(...\) defines a group, and ( and ) are literals. */
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
/* If this bit is set, then \<digit> matches <digit>.
If not set, then \<digit> is a back-reference. */
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
/* If this bit is set, then | is an alternation operator, and \| is literal.
If not set, then \| is an alternation operator, and | is literal. */
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
/* If this bit is set, then an ending range point collating higher
than the starting range point, as in [z-a], is invalid.
If not set, then when ending range point collates higher than the
starting range point, the range is ignored. */
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
/* If this bit is set, then an unmatched ) is ordinary.
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */
/* [[[begin syntaxes]]] */
#define RE_SYNTAX_EMACS 0
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_UNMATCHED_RIGHT_PAREN_ORD)
#define RE_SYNTAX_POSIX_AWK \
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
#define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
| RE_NEWLINE_ALT)
#define RE_SYNTAX_EGREP \
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
| RE_NO_BK_VBAR)
#define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
#define _RE_SYNTAX_POSIX_COMMON \
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
#define RE_SYNTAX_POSIX_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
isn't minimal, since other operators, such as \`, aren't disabled. */
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
#define RE_SYNTAX_POSIX_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
| RE_UNMATCHED_RIGHT_PAREN_ORD)
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */
/* Maximum number of duplicates an interval can allow. Some systems
(erroneously) define this in other header files, but we want our
value, so remove any previous define. */
#ifdef RE_DUP_MAX
#undef RE_DUP_MAX
#endif
#define RE_DUP_MAX ((1 << 15) - 1)
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
/* If this bit is set, then use extended regular expression syntax.
If not set, then use basic regular expression syntax. */
#define REG_EXTENDED 1
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
#define REG_ICASE (REG_EXTENDED << 1)
/* If this bit is set, then anchors do not match at newline
characters in the string.
If not set, then anchors do match at newlines. */
#define REG_NEWLINE (REG_ICASE << 1)
/* If this bit is set, then report only success or fail in regexec.
If not set, then returns differ between not matching and errors. */
#define REG_NOSUB (REG_NEWLINE << 1)
/* POSIX `eflags' bits (i.e., information for regexec). */
/* If this bit is set, then the beginning-of-line operator doesn't match
the beginning of the string (presumably because it's not the
beginning of a line).
If not set, then the beginning-of-line operator does match the
beginning of the string. */
#define REG_NOTBOL 1
/* Like REG_NOTBOL, except for the end-of-line. */
#define REG_NOTEOL (1 << 1)
/* If any error codes are removed, changed, or added, update the
`re_error_msg' table in regex.c. */
typedef enum
{
REG_NOERROR = 0, /* Success. */
REG_NOMATCH, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
REG_BADPAT, /* Invalid pattern. */
REG_ECOLLATE, /* Not implemented. */
REG_ECTYPE, /* Invalid character class name. */
REG_EESCAPE, /* Trailing backslash. */
REG_ESUBREG, /* Invalid back reference. */
REG_EBRACK, /* Unmatched left bracket. */
REG_EPAREN, /* Parenthesis imbalance. */
REG_EBRACE, /* Unmatched \{. */
REG_BADBR, /* Invalid contents of \{\}. */
REG_ERANGE, /* Invalid range end. */
REG_ESPACE, /* Ran out of memory. */
REG_BADRPT, /* No preceding re for repetition op. */
/* Error codes we've added. */
REG_EEND, /* Premature end. */
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
} reg_errcode_t;
/* This data structure represents a compiled pattern. Before calling
the pattern compiler, the fields `buffer', `allocated', `fastmap',
`translate', and `no_sub' can be set. After the pattern has been
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
/* Space that holds the compiled pattern. It is declared as
`unsigned char *' because its elements are
sometimes used as array indexes. */
unsigned char *buffer;
/* Number of bytes to which `buffer' points. */
unsigned long allocated;
/* Number of bytes actually used in `buffer'. */
unsigned long used;
/* Syntax setting with which the pattern was compiled. */
reg_syntax_t syntax;
/* Pointer to a fastmap, if any, otherwise zero. re_search uses
the fastmap, if there is one, to skip over impossible
starting points for matches. */
char *fastmap;
/* Either a translate table to apply to all characters before
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
char *translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
/* Zero if this pattern cannot match the empty string, one else.
Well, in truth it's used only in `re_search_2', to see
whether or not we should use the fastmap, so we don't set
this absolutely perfectly; see `re_compile_fastmap' (the
`duplicate' case). */
unsigned can_be_null : 1;
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
for `max (RE_NREGS, re_nsub + 1)' groups.
If REGS_REALLOCATE, reallocate space if necessary.
If REGS_FIXED, use what's there. */
#define REGS_UNALLOCATED 0
#define REGS_REALLOCATE 1
#define REGS_FIXED 2
unsigned regs_allocated : 2;
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned fastmap_accurate : 1;
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned no_sub : 1;
/* If set, a beginning-of-line anchor doesn't match at the
beginning of the string. */
unsigned not_bol : 1;
/* Similarly for an end-of-line anchor. */
unsigned not_eol : 1;
/* If true, an anchor at a newline matches. */
unsigned newline_anchor : 1;
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* search.c (search_buffer) in Emacs needs this one opcode value. It is
defined both in `regex.c' and here. */
#define RE_EXACTN_VALUE 1
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
/* This is the structure we store register match data in. See
regex.texinfo for a full description of what registers match. */
struct re_registers
{
unsigned num_regs;
regoff_t *start;
regoff_t *end;
};
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
`re_match_2' returns information about at least this many registers
the first time a `regs' structure is passed. */
#ifndef RE_NREGS
#define RE_NREGS 30
#endif
/* POSIX specification for registers. Aside from the different names than
`re_registers', POSIX uses an array of structures, instead of a
structure of arrays. */
typedef struct
{
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
} regmatch_t;
/* Declarations for routines. */
/* To avoid duplicating every routine declaration -- once with a
prototype (if we are ANSI), and once without (if we aren't) -- we
use the following macro to declare argument types. This
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
#if __STDC__
#define _RE_ARGS(args) args
#else /* not __STDC__ */
#define _RE_ARGS(args) ()
#endif /* not __STDC__ */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
/* Compile the regular expression PATTERN, with length LENGTH
and syntax given by the global `re_syntax_options', into the buffer
BUFFER. Return NULL if successful, and an error string if not. */
extern const char *re_compile_pattern
_RE_ARGS ((const char *pattern, int length,
struct re_pattern_buffer *buffer));
/* Compile a fastmap for the compiled pattern in BUFFER; used to
accelerate searches. Return 0 if successful and -2 if was an
internal error. */
extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
/* Search in the string STRING (with length LENGTH) for the pattern
compiled into BUFFER. Start searching at position START, for RANGE
characters. Return the starting position of the match, -1 for no
match, or -2 for an internal error. Also return register
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
extern int re_search
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, int range, struct re_registers *regs));
/* Like `re_search', but search in the concatenation of STRING1 and
STRING2. Also, stop searching at index START + STOP. */
extern int re_search_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, int range, struct re_registers *regs, int stop));
/* Like `re_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern int re_match
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, struct re_registers *regs));
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
extern int re_match_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, struct re_registers *regs, int stop));
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
ENDS. Subsequent matches using BUFFER and REGS will use this memory
for recording register information. STARTS and ENDS must be
allocated with malloc, and must each be at least `NUM_REGS * sizeof
(regoff_t)' bytes long.
If NUM_REGS == 0, then subsequent matches should allocate their own
register data.
Unless this function is called, the first search or match using
PATTERN_BUFFER will allocate its own register data, without
freeing the old data. */
extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
/* 4.2 bsd compatibility. */
extern char *re_comp _RE_ARGS ((const char *));
extern int re_exec _RE_ARGS ((const char *));
/* POSIX compatibility. */
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
extern int regexec
_RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags));
extern size_t regerror
_RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
size_t errbuf_size));
extern void regfree _RE_ARGS ((regex_t *preg));
#endif /* not __REGEXP_LIBRARY_H__ */
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -0,0 +1,77 @@
Thu Mar 25 21:23:43 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu)
* debugmalloc.c: #include <string.h>, and remove declaration of
memcpy.
Sun Dec 13 20:59:32 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
* tregress.c (test_regress): Add regression test for matching
"[a-a]" against "a" with the upcase translation map.
* iregex.c (print_regs): Don't print a newline after the register
contents.
(main): Instead, write out newlines here after printing match and
search results; this way, we get a newline whether or not the
pattern matched.
Fri Dec 11 03:30:50 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
* tregress.c (test_regress): Add new test to catch bug fixed by
change to regex.c today.
* Makefile.in (dregex.o): Depend on `../regex.[ch]', not `regex.[ch]'.
Sun Nov 15 07:51:40 1992 Karl Berry (karl@cs.umb.edu)
* debugmalloc.c (memcpy): Declare; also, include <assert.h>.
* psx-interf.c (fill_pmatch): Declare offsets as `regoff_t'
instead of `off_t'.
Thu Nov 12 11:29:58 1992 Karl Berry (karl@cs.umb.edu)
* iregex.c (main): Remove unused variable `c'; initialize
the char array in C code; only call print_regs if the match and
search succeeded.
(strlen): Declare.
* tregress.c (test_regress): Bug from enami.
Tue Nov 10 10:36:53 1992 Karl Berry (karl@cs.umb.edu)
* tregress.c (test_regress): Remove Emacs 19 diff bug from rms, as
it was never the right thing to test anyway, and the test itself
had bugs in it.
Mon Nov 9 10:09:40 1992 Karl Berry (karl@cs.umb.edu)
* tregress.c (test_regress): Bug from meyering.
Thu Sep 24 10:48:34 1992 Karl Berry (karl@cs.umb.edu)
* Makefile.in: avoid $< (except in implicit rule).
Sat Sep 19 15:38:29 1992 Karl Berry (karl@hayley)
* Makefile.in (TAGS): include regex.c and regex.h.
Wed Sep 16 09:29:27 1992 Karl Berry (karl@hayley)
* xmalloc.c (xmalloc): use char *, not void *, as some compilers
bomb out on the latter.
* Makefile.in (LOADLIBES): use LIBS instead, as that what's
Autoconf wants to define.
* other.c: remove tests for ^/$ around newlines.
Tue Sep 15 11:01:15 1992 Karl Berry (karl@hayley)
* fileregex.c (main): call re_search_2 instead of re_search.
* Makefile.in (regex.o): make target dregex.o, so VPATH doesn't
find ../regex.o.
Sun Sep 13 06:50:03 1992 Karl Berry (karl@hayley)
* Created.

View File

@ -0,0 +1,169 @@
# Generated automatically from Makefile.in by configure.
# Makefile for regex testing.
#
# Copyright (C) 1992 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
CPPFLAGS =
CFLAGS = -g
LDFLAGS =
srcdir = .
VPATH = .:../.
CC = gcc
DEFS = -DHAVE_STRING_H=1
LIBS = $(LOADLIBES)
ETAGS = etags
SHELL = /bin/sh
debug = -DDEBUG
ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
.c.o:
$(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
# Define this as `../regex.o' to get the optimized version.
regex_o = dregex.o
test_h = test.h
test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
psx-generic.o psx-group.o psx-interf.o psx-interv.o
common_o = printchar.o upcase.o xmalloc.o $(malloc)
# We have a lot of mallocs we can try when we run afoul of strange bugs.
malloc =
#malloc = # the libc malloc
#malloc = g++malloc.o
#malloc = debugmalloc.o
#malloc = emacsmalloc.o
emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
# default is to do nothing.
default:
all: regex syntax
regex: $(regex_o) $(common_o) $(test_o) main.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
# As long as we're doing tests, we enable debugging.
dregex.o: ../regex.c ../regex.h
rm -f $@
$(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
mv regex.o $@
# iregex is the interactive regex.
iregex: $(common_o) $(regex_o) iregex.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
# fileregex searches for an r.e. in every line of a given file.
fileregex_o = fileregex.o printchar.o $(regex_o)
fileregex: $(fileregex_o)
$(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
# cppregex is regex with a preprocessed regex.c. Useful when the
# problem is inside some macro.
cppregex: regexcpp.o $(common_o) $(test_o) main.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
regexcpp.o: regexcpp.c
regexcpp.c: regex.c regexcpp.sed
rm -f regexcpp.c
$(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
| egrep -v '^#|^ *$$' \
| sed -f regexcpp.sed \
> regexcpp.c
chmod a-w regexcpp.c
# Have to give this malloc special flags.
emacsmalloc.o: emacsmalloc.c
$(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
../$(srcdir)/test/emacsmalloc.c
syntax: syntax.o
$(CC) $(CFLAGS) -o $@ syntax.o
syntax.c: syntax.skel bits
sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
bits: regex.h
sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
| grep "#define RE_.*1" \
| sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
check: regex
./regex
TAGS: regex.c regex.h *.h *.c
$(ETAGS) -t $^
depend:
gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
.PHONY: depend
install:
.PHONY: install
clean mostlyclean:
rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
distclean: clean
rm -f bits syntax.c Makefile
extraclean: distclean
rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
realclean: distclean
rm -f TAGS
Makefile: Makefile.in ../config.status
(cd ..; sh config.status)
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
# Assumes $(distdir) is the place to put our files.
distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
dist: Makefile TAGS
mkdir $(distdir)
ln $(distfiles) $(distdir)
# Automatically-generated dependencies below here.
alloca.o : alloca.c
bsd-interf.o : bsd-interf.c
debugmalloc.o : debugmalloc.c
emacsmalloc.o : emacsmalloc.c getpagesize.h
fileregex.o : fileregex.c .././regex.h
g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
iregex.o : iregex.c .././regex.h
main.o : main.c test.h .././regex.h
malloc-test.o : malloc-test.c
other.o : other.c test.h .././regex.h
printchar.o : printchar.c
psx-basic.o : psx-basic.c test.h .././regex.h
psx-extend.o : psx-extend.c test.h .././regex.h
psx-generic.o : psx-generic.c test.h .././regex.h
psx-group.o : psx-group.c test.h .././regex.h
psx-interf.o : psx-interf.c test.h .././regex.h
psx-interv.o : psx-interv.c test.h .././regex.h
syntax.o : syntax.c .././regex.h
test.o : test.c test.h .././regex.h
tregress.o : tregress.c test.h .././regex.h
upcase.o : upcase.c
xmalloc.o : xmalloc.c

View File

@ -0,0 +1,168 @@
# Makefile for regex testing.
#
# Copyright (C) 1992 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
# the Free Software Foundation; either version 2, 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
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
CPPFLAGS =
CFLAGS = -g
LDFLAGS =
srcdir = @srcdir@
VPATH = @srcdir@:../@srcdir@
CC = @CC@
DEFS = @DEFS@
LIBS = @LIBS@ $(LOADLIBES)
ETAGS = etags
SHELL = /bin/sh
debug = -DDEBUG
ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
.c.o:
$(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
# Define this as `../regex.o' to get the optimized version.
regex_o = dregex.o
test_h = test.h
test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
psx-generic.o psx-group.o psx-interf.o psx-interv.o
common_o = printchar.o upcase.o xmalloc.o $(malloc)
# We have a lot of mallocs we can try when we run afoul of strange bugs.
malloc = @ALLOCA@
#malloc = # the libc malloc
#malloc = g++malloc.o
#malloc = debugmalloc.o
#malloc = emacsmalloc.o
emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
# default is to do nothing.
default:
all: regex syntax
regex: $(regex_o) $(common_o) $(test_o) main.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
# As long as we're doing tests, we enable debugging.
dregex.o: ../regex.c ../regex.h
rm -f $@
$(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
mv regex.o $@
# iregex is the interactive regex.
iregex: $(common_o) $(regex_o) iregex.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
# fileregex searches for an r.e. in every line of a given file.
fileregex_o = fileregex.o printchar.o $(regex_o)
fileregex: $(fileregex_o)
$(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
# cppregex is regex with a preprocessed regex.c. Useful when the
# problem is inside some macro.
cppregex: regexcpp.o $(common_o) $(test_o) main.o
$(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
regexcpp.o: regexcpp.c
regexcpp.c: regex.c regexcpp.sed
rm -f regexcpp.c
$(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
| egrep -v '^#|^ *$$' \
| sed -f regexcpp.sed \
> regexcpp.c
chmod a-w regexcpp.c
# Have to give this malloc special flags.
emacsmalloc.o: emacsmalloc.c
$(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
../$(srcdir)/test/emacsmalloc.c
syntax: syntax.o
$(CC) $(CFLAGS) -o $@ syntax.o
syntax.c: syntax.skel bits
sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
bits: regex.h
sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
| grep "#define RE_.*1" \
| sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
check: regex
./regex
TAGS: regex.c regex.h *.h *.c
$(ETAGS) -t $^
depend:
gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
.PHONY: depend
install:
.PHONY: install
clean mostlyclean:
rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
distclean: clean
rm -f bits syntax.c Makefile
extraclean: distclean
rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
realclean: distclean
rm -f TAGS
Makefile: Makefile.in ../config.status
(cd ..; sh config.status)
# Prevent GNU make 3 from overflowing arg limit on system V.
.NOEXPORT:
# Assumes $(distdir) is the place to put our files.
distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
dist: Makefile TAGS
mkdir $(distdir)
ln $(distfiles) $(distdir)
# Automatically-generated dependencies below here.
alloca.o : alloca.c
bsd-interf.o : bsd-interf.c
debugmalloc.o : debugmalloc.c
emacsmalloc.o : emacsmalloc.c getpagesize.h
fileregex.o : fileregex.c .././regex.h
g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
iregex.o : iregex.c .././regex.h
main.o : main.c test.h .././regex.h
malloc-test.o : malloc-test.c
other.o : other.c test.h .././regex.h
printchar.o : printchar.c
psx-basic.o : psx-basic.c test.h .././regex.h
psx-extend.o : psx-extend.c test.h .././regex.h
psx-generic.o : psx-generic.c test.h .././regex.h
psx-group.o : psx-group.c test.h .././regex.h
psx-interf.o : psx-interf.c test.h .././regex.h
psx-interv.o : psx-interv.c test.h .././regex.h
syntax.o : syntax.c .././regex.h
test.o : test.c test.h .././regex.h
tregress.o : tregress.c test.h .././regex.h
upcase.o : upcase.c
xmalloc.o : xmalloc.c

373
gnu/lib/libregex/test/TAGS Normal file
View File

@ -0,0 +1,373 @@
.././regex.c,4137
#define AT_STRINGS_BEG(3078,98376
#define AT_STRINGS_END(3079,98449
#define AT_WORD_BOUNDARY(3093,99002
#define BUF_PUSH(887,24995
#define BUF_PUSH_2(895,25208
#define BUF_PUSH_3(904,25437
#define DEBUG_POP(2336,74614
#define DEBUG_PRINT1(471,14296
#define DEBUG_PRINT1(785,21263
#define DEBUG_PRINT2(472,14342
#define DEBUG_PRINT3(473,14398
#define DEBUG_PRINT3(787,21316
#define DEBUG_PRINT4(474,14462
#define DEBUG_PRINT_COMPILED_PATTERN(475,14534
#define DEBUG_PRINT_COMPILED_PATTERN(789,21386
#define DEBUG_PRINT_DOUBLE_STRING(477,14637
#define DEBUG_PUSH(2338,74684
#define DEBUG_STATEMENT(470,14267
#define DOUBLE_FAIL_STACK(2299,73230
#define EVER_MATCHED_SOMETHING(3028,96680
#define EXTEND_BUFFER(941,26834
#define EXTRACT_NUMBER(403,12499
#define EXTRACT_NUMBER(422,12960
#define EXTRACT_NUMBER_AND_INCR(430,13181
#define EXTRACT_NUMBER_AND_INCR(448,13583
#define FAIL_STACK_EMPTY(2271,72289
#define FAIL_STACK_FULL(2273,72404
#define FAIL_STACK_PTR_EMPTY(2272,72344
#define FAIL_STACK_TOP(2274,72473
#define FIRST_STRING_P(221,5848
#define FREE_VAR(3100,99186
#define FREE_VARIABLES(3101,99240
#define FREE_VARIABLES(3116,99751
#define GET_BUFFER_SPACE(882,24802
#define GET_UNSIGNED_NUMBER(1017,29312
#define INIT_FAIL_STACK(2279,72612
#define INSERT_JUMP(923,26079
#define INSERT_JUMP2(927,26236
#define ISALNUM(147,3407
#define ISALPHA(148,3455
#define ISBLANK(135,3062
#define ISBLANK(137,3116
#define ISCNTRL(149,3503
#define ISDIGIT(146,3359
#define ISGRAPH(140,3185
#define ISGRAPH(142,3239
#define ISLOWER(150,3551
#define ISPRINT(145,3311
#define ISPUNCT(151,3599
#define ISSPACE(152,3647
#define ISUPPER(153,3695
#define ISXDIGIT(154,3743
#define IS_ACTIVE(3026,96578
#define IS_CHAR_CLASS(1035,29793
#define MATCHED_SOMETHING(3027,96621
#define MAX(233,6292
#define MIN(234,6334
#define PATFETCH(852,23769
#define PATFETCH_RAW(860,24020
#define POINTER_TO_OFFSET(3050,97433
#define POP_FAILURE_ITEM(2331,74426
#define POP_FAILURE_POINT(2461,79538
#define PREFETCH(3064,97916
#define PUSH_FAILURE_ITEM(2327,74253
#define PUSH_FAILURE_POINT(2352,75048
#define PUSH_PATTERN_OP(2317,73841
#define REGEX_REALLOCATE(185,4875
#define REGEX_REALLOCATE(210,5495
#define REGEX_TALLOC(227,6137
#define REG_MATCH_NULL_STRING_P(3025,96511
#define REG_UNSET(3055,97649
#define RETALLOC(226,6058
#define SET_LIST_BIT(1011,29089
#define SET_REGS_MATCHED(3034,96936
#define SIGN_EXTEND_CHAR(166,4109
#define SIGN_EXTEND_CHAR(169,4217
#define STORE_JUMP(915,25800
#define STORE_JUMP2(919,25917
#define STORE_NUMBER(384,11919
#define STORE_NUMBER_AND_INCR(394,12242
#define STREQ(231,6244
#define SYNTAX(120,2790
#define TALLOC(225,6003
#define TRANSLATE(873,24503
#define WORDCHAR_P(3086,98755
alt_match_null_string_p 4466,149039
#define assert(782,21217
at_begline_loc_p 2131,67979
at_endline_loc_p 2150,68557
#define bcmp(54,1656
bcmp_translate 4591,151831
#define bcopy(57,1726
typedef char boolean;236,6377
#define bzero(60,1793
common_op_match_null_string_p 4503,149895
compile_range 2200,69997
} compile_stack_elt_t;990,28602
} compile_stack_type;998,28748
extract_number 411,12714
extract_number_and_incr 438,13370
} fail_stack_type;2269,72269
group_in_compile_stack 2172,69174
group_match_null_string_p 4357,145267
init_syntax_once 94,2365
insert_op1 2091,67107
insert_op2 2110,67475
#define isascii(131,3018
typedef int pattern_offset_t;981,28388
print_compiled_pattern 726,19792
print_double_string 753,20605
print_fastmap 486,14835
print_partial_compiled_pattern 518,15475
re_comp 4650,153479
re_compile_fastmap 2532,82428
re_compile_pattern 4617,152520
re_exec 4688,154373
re_match 3136,100557
re_match_2 3161,101399
} re_opcode_t;378,11781
re_search 2844,90872
re_search_2 2877,91998
re_set_registers 2817,90247
re_set_syntax 808,22087
regcomp 4736,155972
regerror 4876,160188
regex_compile 1062,30922
regexec 4811,158371
regfree 4920,161247
} register_info_type;3023,96488
typedef unsigned regnum_t;974,28172
store_op1 2063,66535
store_op2 2076,66768
typedef const unsigned 2262,72103
.././regex.h,230
#define _RE_ARGS(394,14981
#define _RE_ARGS(398,15036
} reg_errcode_t;270,10874
typedef unsigned reg_syntax_t;38,1503
typedef struct re_pattern_buffer regex_t;346,13556
} regmatch_t;382,14634
typedef int regoff_t;354,13814
getpagesize.h,84
#define getpagesize(12,137
#define getpagesize(15,191
#define getpagesize(20,302
test.h,436
#define BRACES_TO_OPS(107,3169
#define INVALID_PATTERN(110,3328
#define MATCH_SELF(114,3429
#define PARENS_TO_OPS(108,3248
#define SAFE_STRLEN(14,201
#define TEST_POSITIONED_MATCH(116,3470
#define TEST_REGISTERS(104,3011
#define TEST_REGISTERS_2(97,2703
#define TEST_SEARCH(127,3875
#define TEST_SEARCH_2(123,3720
#define TEST_TRUNCATED_MATCH(120,3608
typedef enum { false = 0, true = 1 } boolean;16,255
} test_type;33,572
alloca.c,128
alloca 141,3996
find_stack_direction 85,2553
} header;127,3538
typedef void *pointer;51,1721
typedef char *pointer;53,1778
bsd-interf.c,51
test_berk_search 8,106
test_bsd_interface 33,738
debugmalloc.c,395
#define TRACE(8,143
#define TRACE1(9,197
#define TRACE2(10,254
#define TRACE3(11,319
#define TRACE4(12,392
#define USER_ALLOC(61,1440
typedef char *address;15,480
} *chunk;54,1225
chunk_delete 115,2778
chunk_insert 96,2294
chunk_to_mem 79,1916
free 261,5604
free_list_available 175,3947
malloc 203,4343
mem_to_chunk 68,1703
realloc 242,5309
validate_list 153,3478
xsbrk 21,545
emacsmalloc.c,574
#define ASSERT(178,5884
#define ASSERT(181,5985
#define CHAIN(166,5430
#define bcmp(73,2821
#define bcopy(72,2777
#define bzero(74,2868
calloc 603,15983
free 484,13255
get_lim_data 736,18517
get_lim_data 752,18767
get_lim_data 759,18860
getpool 374,10263
malloc 413,11133
malloc_init 218,6863
malloc_mem_free 707,17940
malloc_mem_used 688,17683
malloc_stats 663,17320
malloc_usable_size 233,7147
memalign 618,16164
morecore 244,7380
realloc 541,14424
#define start_of_data(110,3486
#define start_of_data(115,3546
sys_sbrk 815,20804
valloc 645,17031
fileregex.c,13
main 11,156
g++malloc.c,1543
#define UPDATE_STATS(33,1090
#define UPDATE_STATS(35,1131
static inline int aligned_OK(343,11189
void* calloc(1039,28692
void cfree(1048,28894
static inline void* chunk2mem(619,19336
#define clear_inuse(592,18767
static inline void consollink(716,21398
static void do_free_stats(544,18016
static void do_malloc_stats(534,17741
766,22304
extern 762,22235
for 1260,34165
void free(1028,28553
static inline void frontlink(732,21717
static unsigned int gcd(557,18251
if 1212,32427
if 1216,32582
if 1220,32737
if 1224,32880
if 1229,33094
if 1233,33251
if 1238,33463
if 1242,33609
if 1247,33739
#define inuse(590,18680
static inline unsigned int lcm(580,18540
void* malloc(939,26370
static mchunkptr malloc_find_space(858,24561
void malloc_stats(1201,32256
unsigned int malloc_usable_size(1054,28936
static volatile void malloc_user_error(286,9757
static void malloc_user_error(288,9804
typedef struct malloc_bin* mbinptr;320,10636
typedef struct malloc_chunk* mchunkptr;309,10247
static inline mchunkptr mem2chunk(643,19759
void* memalign(1118,30363
#define next_chunk(600,18910
#define prev_chunk(604,19023
void* realloc(1071,29263
static inline unsigned int request2size(335,10993
mchunkptr sanity_check(628,19486
#define set_inuse(591,18723
static inline void set_size(609,19149
static inline mbinptr size2bin(499,16914
static inline void split(685,20463
static 768,22312
static inline void unlink(671,20263
void* valloc(1194,32107
typedef volatile void 760,22184
764,22271
iregex.c,54
main 20,390
print_regs 141,2638
scanstring 87,1839
main.c,13
main 12,242
malloc-test.c,112
#define BITS_BLOCK(12,168
#define BITS_MASK(13,228
} bits_list_type;6,56
init_bits_list 16,311
main(32,621
other.c,18
test_others 6,96
printchar.c,15
printchar 2,5
psx-basic.c,23
test_posix_basic 7,84
psx-extend.c,26
test_posix_extended 7,88
psx-generic.c,26
test_posix_generic 8,117
psx-group.c,20
test_grouping 7,92
psx-interf.c,416
fill_pmatch 174,4802
get_error_string 18,260
init_pattern_buffer 49,1434
test_compile 67,1925
test_eflags 245,6876
test_error_code_allocation 562,16619
test_error_code_message 524,15247
test_ignore_case 303,8525
test_newline 330,9199
test_nsub 117,3319
test_pmatch 188,5121
test_posix_interface 614,18719
test_posix_match 359,9938
test_regcomp 138,3725
test_regerror 592,17621
test_regexec 394,10783
psx-interv.c,21
test_intervals 6,93
test.c,607
#define SET_FASTMAP(447,13999
#define bcmp(18,362
#define bcopy(19,415
#define bzero(20,473
compile_and_print_pattern 666,19653
concat 97,2673
delimiters_to_ops 571,17477
general_test 115,2996
invalid_pattern 542,16821
#define memcmp(26,611
#define memcpy(27,660
print_pattern_info 635,18998
set_all_registers 58,1390
test_all_registers 506,15567
test_case_fold 682,19993
test_fastmap 460,14363
test_fastmap_search 474,14668
test_match 776,22235
test_match_2 766,22040
test_match_n_times 715,20798
test_search_return 408,13011
valid_nonposix_pattern 646,19239
valid_pattern 557,17182
tregress.c,208
#define SIMPLE_MATCH(74,1463
#define SIMPLE_NONMATCH(75,1528
do_match 78,1599
itoa 10,199
simple_compile 44,882
simple_fail 21,353
simple_fastmap 55,1115
simple_search 100,2020
test_regress 124,2513
upcase.c,0
xmalloc.c,14
xmalloc 9,87

View File

@ -0,0 +1,194 @@
/*
alloca -- (mostly) portable public-domain implementation -- D A Gwyn
last edit: 86/05/30 rms
include config.h, since on VMS it renames some symbols.
Use xmalloc instead of malloc.
This implementation of the PWB library alloca() function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
It should work under any C implementation that uses an
actual procedure stack (as opposed to a linked list of
frames). There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca()-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection.
*/
#ifndef lint
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
#endif
#ifdef emacs
#include "config.h"
#ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
#ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
#endif /* STACK_DIRECTION undefined */
#endif /* static */
#endif /* emacs */
#ifndef alloca /* If compiling with GCC, this file's not needed. */
#ifdef __STDC__
typedef void *pointer; /* generic pointer type */
#else
typedef char *pointer; /* generic pointer type */
#endif
#define NULL 0 /* null pointer constant */
extern void free();
extern pointer xmalloc();
/*
Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* direction unknown */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* known at compile-time */
#else /* STACK_DIRECTION == 0; need run-time code */
static int stack_dir; /* 1 or -1 once known */
#define STACK_DIR stack_dir
static void
find_stack_direction (/* void */)
{
static char *addr = NULL; /* address of first
`dummy', once known */
auto char dummy; /* to get stack address */
if (addr == NULL)
{ /* initial entry */
addr = &dummy;
find_stack_direction (); /* recurse once */
}
else /* second entry */
if (&dummy > addr)
stack_dir = 1; /* stack grew upward */
else
stack_dir = -1; /* stack grew downward */
}
#endif /* STACK_DIRECTION == 0 */
/*
An "alloca header" is used to:
(a) chain together all alloca()ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc()
alignment chunk size. The following default should work okay.
*/
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* to force sizeof(header) */
struct
{
union hdr *next; /* for chaining headers */
char *deep; /* for stack depth measure */
} h;
} header;
/*
alloca( size ) returns a pointer to at least `size' bytes of
storage which will be automatically reclaimed upon exit from
the procedure that called alloca(). Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32.
*/
static header *last_alloca_header = NULL; /* -> last alloca header */
pointer
alloca (size) /* returns pointer to storage */
unsigned size; /* # bytes to allocate */
{
auto char probe; /* probes stack depth: */
register char *depth = &probe;
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* unknown growth direction */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca()ed storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* traverses linked list */
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((pointer) hp); /* collect garbage */
hp = np; /* -> next header */
}
else
break; /* rest are not deeper */
last_alloca_header = hp; /* -> last valid storage */
}
if (size == 0)
return NULL; /* no allocation required */
/* Allocate combined header + user data storage. */
{
register pointer new = xmalloc (sizeof (header) + size);
/* address of header */
((header *)new)->h.next = last_alloca_header;
((header *)new)->h.deep = depth;
last_alloca_header = (header *)new;
/* User storage begins just after header. */
return (pointer)((char *)new + sizeof(header));
}
}
#endif /* no alloca */

View File

@ -0,0 +1,38 @@
/* bsd-interf.c: test BSD interface. */
#ifndef _POSIX_SOURCE /* whole file */
#include "test.h"
void
test_berk_search (pattern, string)
const char *pattern;
char *string;
{
const char *return_value = re_comp (pattern);
if (return_value != 0)
{
printf ("This didn't compile: `%s'.\n", pattern);
printf (" The error message was: `%s'.\n", return_value);
}
else
if (test_should_match && re_exec (string) != strlen (string))
{
printf ("Should have matched but didn't:\n");
printf (" The pattern was: %s.\n", pattern);
if (string)
printf (" The string was: `%s'.'n", string);
else
printf (" The string was empty.\n");
}
}
void
test_bsd_interface ()
{
test_berk_search ("a", "ab");
}
#endif /* _POSIX_SOURCE */

View File

@ -0,0 +1,273 @@
/* debugmalloc.c: a malloc for debugging purposes. */
#include <stdio.h>
#include <assert.h>
#include <string.h>
static unsigned trace = 0;
#define TRACE(s) if (trace) fprintf (stderr, "%s", s)
#define TRACE1(s, e1) if (trace) fprintf (stderr, s, e1)
#define TRACE2(s, e1, e2) if (trace) fprintf (stderr, s, e1, e2)
#define TRACE3(s, e1, e2, e3) if (trace) fprintf (stderr, s, e1, e2, e3)
#define TRACE4(s, e1, e2, e3, e4) \
if (trace) fprintf (stderr, s, e1, e2, e3, e4)
typedef char *address;
/* Wrap our calls to sbrk. */
address
xsbrk (incr)
int incr;
{
extern char *sbrk ();
address ret = sbrk (incr);
if (ret == (address) -1)
{
perror ("sbrk"); /* Actually, we should return NULL, not quit. */
abort ();
}
return ret;
}
typedef struct chunk_struct
{
/* This is the size (in bytes) that has actually been actually
allocated, not the size that the user requested. */
unsigned alloc_size;
/* This is the size the user requested. */
unsigned user_size;
/* Points to the next block in one of the lists. */
struct chunk_struct *next;
/* Now comes the user's memory. */
address user_mem;
/* After the user's memory is a constant. */
} *chunk;
#define MALLOC_OVERHEAD 16
/* We might play around with the `user_size' field, but the amount of
memory that is actually available in the chunk is always the size
allocated minus the overhead. */
#define USER_ALLOC(c) ((c)->alloc_size - MALLOC_OVERHEAD)
/* Given a pointer to a malloc-allocated block, the beginning of the
chunk should always be MALLOC_OVERHEAD - 4 bytes back, since the only
overhead after the user memory is the constant. */
chunk
mem_to_chunk (mem)
address mem;
{
return (chunk) (mem - (MALLOC_OVERHEAD - 4));
}
/* The other direction is even easier, since the user's memory starts at
the `user_mem' member in the chunk. */
address
chunk_to_mem (c)
chunk c;
{
return (address) &(c->user_mem);
}
/* We keep both all the allocated chunks and all the free chunks on
lists. Since we put the next pointers in the chunk structure, we
don't need a separate chunk_list structure. */
chunk alloc_list = NULL, free_list = NULL;
/* We always append the new chunk at the beginning of the list. */
void
chunk_insert (chunk_list, new_c)
chunk *chunk_list;
chunk new_c;
{
chunk c = *chunk_list; /* old beginning of list */
TRACE3 (" Inserting 0x%x at the beginning of 0x%x, before 0x%x.\n",
new_c, chunk_list, c);
*chunk_list = new_c;
new_c->next = c;
}
/* Thus, removing an element means we have to search until we find it.
Have to delete before we insert, since insertion changes the next
pointer, which we need to put it on the other list. */
void
chunk_delete (chunk_list, dead_c)
chunk *chunk_list;
chunk dead_c;
{
chunk c = *chunk_list;
chunk prev_c = NULL;
TRACE2 (" Deleting 0x%x from 0x%x:", dead_c, chunk_list);
while (c != dead_c && c != NULL)
{
TRACE1 (" 0x%x", c);
prev_c = c;
c = c->next;
}
if (c == NULL)
{
fprintf (stderr, "Chunk at 0x%x not found on list.\n", dead_c);
abort ();
}
if (prev_c == NULL)
{
TRACE1 (".\n Setting head to 0x%x.\n", c->next);
*chunk_list = c->next;
}
else
{
TRACE2 (".\n Linking next(0x%x) to 0x%x.\n", prev_c, c->next);
prev_c->next = c->next;
}
}
/* See if a list is hunky-dory. */
void
validate_list (chunk_list)
chunk *chunk_list;
{
chunk c;
TRACE1 (" Validating list at 0x%x:", chunk_list);
for (c = *chunk_list; c != NULL; c = c->next)
{
assert (c->user_size < c->alloc_size);
assert (memcmp (chunk_to_mem (c) + c->user_size, "Karl", 4));
TRACE2 (" 0x%x/%d", c, c->user_size);
}
TRACE (".\n");
}
/* See if we have a free chunk of a given size. We'll take the first
one that is big enough. */
chunk
free_list_available (needed)
unsigned needed;
{
chunk c;
TRACE1 (" Checking free list for %d bytes:", needed);
if (free_list == NULL)
{
return NULL;
}
c = free_list;
while (c != NULL && USER_ALLOC (c) < needed)
{
TRACE2 (" 0x%x/%d", c, USER_ALLOC (c));
c = c->next;
}
TRACE1 ("\n Returning 0x%x.\n", c);
return c;
}
address
malloc (n)
unsigned n;
{
address new_mem;
chunk c;
TRACE1 ("Mallocing %d bytes.\n", n);
validate_list (&free_list);
validate_list (&alloc_list);
c = free_list_available (n);
if (c == NULL)
{ /* Nothing suitable on free list. Allocate a new chunk. */
TRACE (" not on free list.\n");
c = (chunk) xsbrk (n + MALLOC_OVERHEAD);
c->alloc_size = n + MALLOC_OVERHEAD;
}
else
{ /* Found something on free list. Don't split it, just use as is. */
TRACE (" found on free list.\n");
chunk_delete (&free_list, c);
}
/* If we took this from the free list, then the user size might be
different now, and consequently the constant at the end might be in
the wrong place. */
c->user_size = n;
new_mem = chunk_to_mem (c);
memcpy (new_mem + n, "Karl", 4);
chunk_insert (&alloc_list, c);
TRACE2 ("Malloc returning 0x%x (chunk 0x%x).\n", new_mem, c);
return new_mem;
}
address
realloc (mem, n)
address mem;
unsigned n;
{
void free ();
chunk c = mem_to_chunk (mem);
address new_mem;
TRACE3 ("Reallocing %d bytes at 0x%x (chunk 0x%x).\n", n, mem, c);
new_mem = malloc (n);
memcpy (new_mem, mem, c->user_size);
free (mem);
return new_mem;
}
void
free (mem)
address mem;
{
chunk c = mem_to_chunk (mem);
TRACE2 ("Freeing memory at 0x%x (chunk at 0x%x).\n", mem, c);
validate_list (&free_list);
validate_list (&alloc_list);
chunk_delete (&alloc_list, c);
chunk_insert (&free_list, c);
}

View File

@ -0,0 +1,844 @@
/* dynamic memory allocation for GNU.
Copyright (C) 1985, 1987 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
the Free Software Foundation; either version 1, 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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
/*
* @(#)nmalloc.c 1 (Caltech) 2/21/82
*
* U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
*
* Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks
* that don't exactly fit are passed up to the next larger size. In this
* implementation, the available sizes are (2^n)-4 (or -16) bytes long.
* This is designed for use in a program that uses vast quantities of
* memory, but bombs when it runs out. To make it a little better, it
* warns the user when he starts to get near the end.
*
* June 84, ACT: modified rcheck code to check the range given to malloc,
* rather than the range determined by the 2-power used.
*
* Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
* No longer Emacs-specific; can serve as all-purpose malloc for GNU.
* You should call malloc_init to reinitialize after loading dumped Emacs.
* Call malloc_stats to get info on memory stats if MSTATS turned on.
* realloc knows how to return same block given, just changing its size,
* if the power of 2 is correct.
*/
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information will
* go in the first int of the block, and the returned pointer will point
* to the second.
*
#ifdef MSTATS
* nmalloc[i] is the difference between the number of mallocs and frees
* for a given block size.
#endif MSTATS
*/
#ifdef emacs
/* config.h specifies which kind of system this is. */
#include "config.h"
#include <signal.h>
#else
/* Determine which kind of system this is. */
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#define bcopy(s,d,n) memcpy ((d), (s), (n))
#define bcmp(s1,s2,n) memcmp ((s1), (s2), (n))
#define bzero(s,n) memset ((s), 0, (n))
#ifndef SIGTSTP
#ifndef VMS
#ifndef USG
#define USG
#endif
#endif /* not VMS */
#else /* SIGTSTP */
#ifdef SIGIO
#define BSD4_2
#endif /* SIGIO */
#endif /* SIGTSTP */
#endif /* not emacs */
/* Define getpagesize () if the system does not. */
#include "getpagesize.h"
#ifdef BSD
#ifdef BSD4_1
#include <sys/vlimit.h> /* warn the user when near the end */
#else /* if 4.2 or newer */
#include <sys/time.h>
#include <sys/resource.h>
#endif /* if 4.2 or newer */
#endif
#ifdef VMS
#include "vlimit.h"
#endif
extern char *start_of_data ();
#ifdef BSD
#ifndef DATA_SEG_BITS
#define start_of_data() &etext
#endif
#endif
#ifndef emacs
#define start_of_data() &etext
#endif
#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
#define ISFREE ((char) 0x54) /* magic byte that implies free block */
/* this is for error checking only */
#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
memalign, with the rest of the word
being the distance to the true
beginning of the block. */
extern char etext;
/* These two are for user programs to look at, when they are interested. */
unsigned int malloc_sbrk_used; /* amount of data space used now */
unsigned int malloc_sbrk_unused; /* amount more we can have */
/* start of data space; can be changed by calling init_malloc */
static char *data_space_start;
#ifdef MSTATS
static int nmalloc[30];
static int nmal, nfre;
#endif /* MSTATS */
/* If range checking is not turned on, all we have is a flag indicating
whether memory is allocated, an index in nextf[], and a size field; to
realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
on whether the former can hold the exact size (given the value of
'index'). If range checking is on, we always need to know how much space
is allocated, so the 'size' field is never used. */
struct mhead {
char mh_alloc; /* ISALLOC or ISFREE */
char mh_index; /* index in nextf[] */
/* Remainder are valid only when block is allocated */
unsigned short mh_size; /* size, if < 0x10000 */
#ifdef rcheck
unsigned mh_nbytes; /* number of bytes allocated */
int mh_magic4; /* should be == MAGIC4 */
#endif /* rcheck */
};
/* Access free-list pointer of a block.
It is stored at block + 4.
This is not a field in the mhead structure
because we want sizeof (struct mhead)
to describe the overhead for when the block is in use,
and we do not want the free-list pointer to count in that. */
#define CHAIN(a) \
(*(struct mhead **) (sizeof (char *) + (char *) (a)))
#ifdef rcheck
/* To implement range checking, we write magic values in at the beginning and
end of each allocated block, and make sure they are undisturbed whenever a
free or a realloc occurs. */
/* Written in each of the 4 bytes following the block's real space */
#define MAGIC1 0x55
/* Written in the 4 bytes before the block's real space */
#define MAGIC4 0x55555555
#define ASSERT(p) if (!(p)) botch("p"); else
#define EXTRA 4 /* 4 bytes extra for MAGIC1s */
#else
#define ASSERT(p) if (!(p)) abort (); else
#define EXTRA 0
#endif /* rcheck */
/* nextf[i] is free list of blocks of size 2**(i + 3) */
static struct mhead *nextf[30];
/* busy[i] is nonzero while allocation of block size i is in progress. */
static char busy[30];
/* Number of bytes of writable memory we can expect to be able to get */
static unsigned int lim_data;
/* Level number of warnings already issued.
0 -- no warnings issued.
1 -- 75% warning already issued.
2 -- 85% warning already issued.
*/
static int warnlevel;
/* Function to call to issue a warning;
0 means don't issue them. */
static void (*warnfunction) ();
/* nonzero once initial bunch of free blocks made */
static int gotpool;
char *_malloc_base;
static void getpool ();
/* Cause reinitialization based on job parameters;
also declare where the end of pure storage is. */
void
malloc_init (start, warnfun)
char *start;
void (*warnfun) ();
{
if (start)
data_space_start = start;
lim_data = 0;
warnlevel = 0;
warnfunction = warnfun;
}
/* Return the maximum size to which MEM can be realloc'd
without actually requiring copying. */
int
malloc_usable_size (mem)
char *mem;
{
struct mhead *p
= (struct mhead *) (mem - ((sizeof (struct mhead) + 7) & ~7));
int blocksize = 8 << p->mh_index;
return blocksize - sizeof (struct mhead) - EXTRA;
}
static void
morecore (nu) /* ask system for more memory */
register int nu; /* size index to get more of */
{
char *sbrk ();
register char *cp;
register int nblks;
register unsigned int siz;
int oldmask;
#ifdef BSD
#ifndef BSD4_1
int newmask = -1;
/* Blocking these signals interferes with debugging, at least on BSD on
the HP 9000/300. */
#ifdef SIGTRAP
newmask &= ~(1 << SIGTRAP);
#endif
#ifdef SIGILL
newmask &= ~(1 << SIGILL);
#endif
#ifdef SIGTSTP
newmask &= ~(1 << SIGTSTP);
#endif
#ifdef SIGSTOP
newmask &= ~(1 << SIGSTOP);
#endif
oldmask = sigsetmask (newmask);
#endif
#endif
if (!data_space_start)
{
data_space_start = start_of_data ();
}
if (lim_data == 0)
get_lim_data ();
/* On initial startup, get two blocks of each size up to 1k bytes */
if (!gotpool)
{ getpool (); getpool (); gotpool = 1; }
/* Find current end of memory and issue warning if getting near max */
#ifndef VMS
/* Maximum virtual memory on VMS is difficult to calculate since it
* depends on several dynmacially changing things. Also, alignment
* isn't that important. That is why much of the code here is ifdef'ed
* out for VMS systems.
*/
cp = sbrk (0);
siz = cp - data_space_start;
if (warnfunction)
switch (warnlevel)
{
case 0:
if (siz > (lim_data / 4) * 3)
{
warnlevel++;
(*warnfunction) ("Warning: past 75% of memory limit");
}
break;
case 1:
if (siz > (lim_data / 20) * 17)
{
warnlevel++;
(*warnfunction) ("Warning: past 85% of memory limit");
}
break;
case 2:
if (siz > (lim_data / 20) * 19)
{
warnlevel++;
(*warnfunction) ("Warning: past 95% of memory limit");
}
break;
}
if ((int) cp & 0x3ff) /* land on 1K boundaries */
sbrk (1024 - ((int) cp & 0x3ff));
#endif /* not VMS */
/* Take at least 2k, and figure out how many blocks of the desired size
we're about to get */
nblks = 1;
if ((siz = nu) < 8)
nblks = 1 << ((siz = 8) - nu);
if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
{
#ifdef BSD
#ifndef BSD4_1
sigsetmask (oldmask);
#endif
#endif
return; /* no more room! */
}
malloc_sbrk_used = siz;
malloc_sbrk_unused = lim_data - siz;
#ifndef VMS
if ((int) cp & 7)
{ /* shouldn't happen, but just in case */
cp = (char *) (((int) cp + 8) & ~7);
nblks--;
}
#endif /* not VMS */
/* save new header and link the nblks blocks together */
nextf[nu] = (struct mhead *) cp;
siz = 1 << (nu + 3);
while (1)
{
((struct mhead *) cp) -> mh_alloc = ISFREE;
((struct mhead *) cp) -> mh_index = nu;
if (--nblks <= 0) break;
CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
cp += siz;
}
CHAIN ((struct mhead *) cp) = 0;
#ifdef BSD
#ifndef BSD4_1
sigsetmask (oldmask);
#endif
#endif
}
static void
getpool ()
{
register int nu;
char * sbrk ();
register char *cp = sbrk (0);
if ((int) cp & 0x3ff) /* land on 1K boundaries */
sbrk (1024 - ((int) cp & 0x3ff));
/* Record address of start of space allocated by malloc. */
if (_malloc_base == 0)
_malloc_base = cp;
/* Get 2k of storage */
cp = sbrk (04000);
if (cp == (char *) -1)
return;
/* Divide it into an initial 8-word block
plus one block of size 2**nu for nu = 3 ... 10. */
CHAIN (cp) = nextf[0];
nextf[0] = (struct mhead *) cp;
((struct mhead *) cp) -> mh_alloc = ISFREE;
((struct mhead *) cp) -> mh_index = 0;
cp += 8;
for (nu = 0; nu < 7; nu++)
{
CHAIN (cp) = nextf[nu];
nextf[nu] = (struct mhead *) cp;
((struct mhead *) cp) -> mh_alloc = ISFREE;
((struct mhead *) cp) -> mh_index = nu;
cp += 8 << nu;
}
}
char *
malloc (n) /* get a block */
unsigned n;
{
register struct mhead *p;
register unsigned int nbytes;
register int nunits = 0;
/* Figure out how many bytes are required, rounding up to the nearest
multiple of 8, then figure out which nestf[] area to use.
Both the beginning of the header and the beginning of the
block should be on an eight byte boundary. */
nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
{
register unsigned int shiftr = (nbytes - 1) >> 2;
while (shiftr >>= 1)
nunits++;
}
/* In case this is reentrant use of malloc from signal handler,
pick a block size that no other malloc level is currently
trying to allocate. That's the easiest harmless way not to
interfere with the other level of execution. */
while (busy[nunits]) nunits++;
busy[nunits] = 1;
/* If there are no blocks of the appropriate size, go get some */
/* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
if (nextf[nunits] == 0)
morecore (nunits);
/* Get one block off the list, and set the new list head */
if ((p = nextf[nunits]) == 0)
{
busy[nunits] = 0;
return 0;
}
nextf[nunits] = CHAIN (p);
busy[nunits] = 0;
/* Check for free block clobbered */
/* If not for this check, we would gobble a clobbered free chain ptr */
/* and bomb out on the NEXT allocate of this size block */
if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
#ifdef rcheck
botch ("block on free list clobbered");
#else /* not rcheck */
abort ();
#endif /* not rcheck */
/* Fill in the info, and if range checking, set up the magic numbers */
p -> mh_alloc = ISALLOC;
#ifdef rcheck
p -> mh_nbytes = n;
p -> mh_magic4 = MAGIC4;
{
/* Get the location n after the beginning of the user's space. */
register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n;
*m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
}
#else /* not rcheck */
p -> mh_size = n;
#endif /* not rcheck */
#ifdef MSTATS
nmalloc[nunits]++;
nmal++;
#endif /* MSTATS */
return (char *) p + ((sizeof *p + 7) & ~7);
}
free (mem)
char *mem;
{
register struct mhead *p;
{
register char *ap = mem;
if (ap == 0)
return;
p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
if (p -> mh_alloc == ISMEMALIGN)
{
ap -= p->mh_size;
p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
}
#ifndef rcheck
if (p -> mh_alloc != ISALLOC)
abort ();
#else rcheck
if (p -> mh_alloc != ISALLOC)
{
if (p -> mh_alloc == ISFREE)
botch ("free: Called with already freed block argument\n");
else
botch ("free: Called with bad argument\n");
}
ASSERT (p -> mh_magic4 == MAGIC4);
ap += p -> mh_nbytes;
ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
#endif /* rcheck */
}
{
register int nunits = p -> mh_index;
ASSERT (nunits <= 29);
p -> mh_alloc = ISFREE;
/* Protect against signal handlers calling malloc. */
busy[nunits] = 1;
/* Put this block on the free list. */
CHAIN (p) = nextf[nunits];
nextf[nunits] = p;
busy[nunits] = 0;
#ifdef MSTATS
nmalloc[nunits]--;
nfre++;
#endif /* MSTATS */
}
}
char *
realloc (mem, n)
char *mem;
register unsigned n;
{
register struct mhead *p;
register unsigned int tocopy;
register unsigned int nbytes;
register int nunits;
if (mem == 0)
return malloc (n);
p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7));
nunits = p -> mh_index;
ASSERT (p -> mh_alloc == ISALLOC);
#ifdef rcheck
ASSERT (p -> mh_magic4 == MAGIC4);
{
register char *m = mem + (tocopy = p -> mh_nbytes);
ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
}
#else /* not rcheck */
if (p -> mh_index >= 13)
tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7);
else
tocopy = p -> mh_size;
#endif /* not rcheck */
/* See if desired size rounds to same power of 2 as actual size. */
nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
/* If ok, use the same block, just marking its size as changed. */
if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
{
#ifdef rcheck
register char *m = mem + tocopy;
*m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
p-> mh_nbytes = n;
m = mem + n;
*m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
#else /* not rcheck */
p -> mh_size = n;
#endif /* not rcheck */
return mem;
}
if (n < tocopy)
tocopy = n;
{
register char *new;
if ((new = malloc (n)) == 0)
return 0;
bcopy (mem, new, tocopy);
free (mem);
return new;
}
}
/* This is in case something linked with Emacs calls calloc. */
char *
calloc (num, size)
unsigned num, size;
{
register char *mem;
num *= size;
mem = malloc (num);
if (mem != 0)
bzero (mem, num);
return mem;
}
#ifndef VMS
char *
memalign (alignment, size)
unsigned alignment, size;
{
register char *ptr = malloc (size + alignment);
register char *aligned;
register struct mhead *p;
if (ptr == 0)
return 0;
/* If entire block has the desired alignment, just accept it. */
if (((int) ptr & (alignment - 1)) == 0)
return ptr;
/* Otherwise, get address of byte in the block that has that alignment. */
aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
/* Store a suitable indication of how to free the block,
so that free can find the true beginning of it. */
p = (struct mhead *) (aligned - ((7 + sizeof (struct mhead)) & ~7));
p -> mh_size = aligned - ptr;
p -> mh_alloc = ISMEMALIGN;
return aligned;
}
#ifndef HPUX
/* This runs into trouble with getpagesize on HPUX.
Patching out seems cleaner than the ugly fix needed. */
char *
valloc (size)
{
return memalign (getpagesize (), size);
}
#endif /* not HPUX */
#endif /* not VMS */
#ifdef MSTATS
/* Return statistics describing allocation of blocks of size 2**n. */
struct mstats_value
{
int blocksize;
int nfree;
int nused;
};
struct mstats_value
malloc_stats (size)
int size;
{
struct mstats_value v;
register int i;
register struct mhead *p;
v.nfree = 0;
if (size < 0 || size >= 30)
{
v.blocksize = 0;
v.nused = 0;
return v;
}
v.blocksize = 1 << (size + 3);
v.nused = nmalloc[size];
for (p = nextf[size]; p; p = CHAIN (p))
v.nfree++;
return v;
}
int
malloc_mem_used ()
{
int i;
int size_used;
size_used = 0;
for (i = 0; i < 30; i++)
{
int allocation_size = 1 << (i + 3);
struct mhead *p;
size_used += nmalloc[i] * allocation_size;
}
return size_used;
}
int
malloc_mem_free ()
{
int i;
int size_unused;
size_unused = 0;
for (i = 0; i < 30; i++)
{
int allocation_size = 1 << (i + 3);
struct mhead *p;
for (p = nextf[i]; p ; p = CHAIN (p))
size_unused += allocation_size;
}
return size_unused;
}
#endif /* MSTATS */
/*
* This function returns the total number of bytes that the process
* will be allowed to allocate via the sbrk(2) system call. On
* BSD systems this is the total space allocatable to stack and
* data. On USG systems this is the data space only.
*/
#ifdef USG
get_lim_data ()
{
extern long ulimit ();
#ifdef ULIMIT_BREAK_VALUE
lim_data = ULIMIT_BREAK_VALUE;
#else
lim_data = ulimit (3, 0);
#endif
lim_data -= (long) data_space_start;
}
#else /* not USG */
#if defined (BSD4_1) || defined (VMS)
get_lim_data ()
{
lim_data = vlimit (LIM_DATA, -1);
}
#else /* not BSD4_1 and not VMS */
get_lim_data ()
{
struct rlimit XXrlimit;
getrlimit (RLIMIT_DATA, &XXrlimit);
#ifdef RLIM_INFINITY
lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
#else
lim_data = XXrlimit.rlim_cur; /* soft limit */
#endif
}
#endif /* not BSD4_1 and not VMS */
#endif /* not USG */
#ifdef VMS
/* There is a problem when dumping and restoring things on VMS. Calls
* to SBRK don't necessarily result in contiguous allocation. Dumping
* doesn't work when it isn't. Therefore, we make the initial
* allocation contiguous by allocating a big chunk, and do SBRKs from
* there. Once Emacs has dumped there is no reason to continue
* contiguous allocation, malloc doesn't depend on it.
*
* There is a further problem of using brk and sbrk while using VMS C
* run time library routines malloc, calloc, etc. The documentation
* says that this is a no-no, although I'm not sure why this would be
* a problem. In any case, we remove the necessity to call brk and
* sbrk, by calling calloc (to assure zero filled data) rather than
* sbrk.
*
* VMS_ALLOCATION_SIZE is the size of the allocation array. This
* should be larger than the malloc size before dumping. Making this
* too large will result in the startup procedure slowing down since
* it will require more space and time to map it in.
*
* The value for VMS_ALLOCATION_SIZE in the following define was determined
* by running emacs linked (and a large allocation) with the debugger and
* looking to see how much storage was used. The allocation was 201 pages,
* so I rounded it up to a power of two.
*/
#ifndef VMS_ALLOCATION_SIZE
#define VMS_ALLOCATION_SIZE (512*256)
#endif
/* Use VMS RTL definitions */
#undef sbrk
#undef brk
#undef malloc
int vms_out_initial = 0;
char vms_initial_buffer[VMS_ALLOCATION_SIZE];
static char *vms_current_brk = &vms_initial_buffer;
static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1];
#include <stdio.h>
char *
sys_sbrk (incr)
int incr;
{
char *sbrk(), *temp, *ptr;
if (vms_out_initial)
{
/* out of initial allocation... */
if (!(temp = malloc (incr)))
temp = (char *) -1;
}
else
{
/* otherwise, go out of our area */
ptr = vms_current_brk + incr; /* new current_brk */
if (ptr <= vms_end_brk)
{
temp = vms_current_brk;
vms_current_brk = ptr;
}
else
{
vms_out_initial = 1; /* mark as out of initial allocation */
if (!(temp = malloc (incr)))
temp = (char *) -1;
}
}
return temp;
}
#endif /* VMS */

View File

@ -0,0 +1,77 @@
#include <sys/types.h>
#include <stdio.h>
#include "regex.h"
#define BYTEWIDTH 8
/* Sorry, but this is just a test program. */
#define LINE_MAX 500
int
main (argc, argv)
int argc;
char *argv[];
{
FILE *f;
char *filename;
char pat[500]; /* Sorry for that maximum size, too. */
char line[LINE_MAX];
struct re_pattern_buffer buf;
char fastmap[(1 << BYTEWIDTH)];
const char *compile_ret;
unsigned lineno = 1;
unsigned nfound = 0;
/* Actually, it might be useful to allow the data file to be standard
input, and to specify the pattern on the command line. */
if (argc != 2)
{
fprintf (stderr, "Usage: %s <filename>.\n", argv[0]);
exit (1);
}
filename = argv[1];
f = fopen (filename, "r");
if (f == NULL)
perror (filename);
buf.allocated = 0;
buf.buffer = NULL;
buf.fastmap = fastmap;
printf ("Pattern = ", pat);
gets (pat);
if (feof (stdin))
{
putchar ('\n');
exit (0);
}
compile_ret = re_compile_pattern (pat, strlen (pat), &buf);
if (compile_ret != NULL)
{
fprintf (stderr, "%s: %s\n", pat, compile_ret);
exit (1);
}
while (fgets (line, LINE_MAX, f) != NULL)
{
size_t len = strlen (line);
struct re_registers regs;
int search_ret
= re_search_2 (&buf, NULL, 0, line, len, 0, len, &regs, len);
if (search_ret == -2)
{
fprintf (stderr, "%s:%d: re_search failed.\n", filename, lineno);
exit (1);
}
nfound += search_ret != -1;
lineno++;
}
printf ("Matches found: %u (out of %u lines).\n", nfound, lineno - 1);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
#ifdef BSD
#ifndef BSD4_1
#define HAVE_GETPAGESIZE
#endif
#endif
#ifndef HAVE_GETPAGESIZE
#include <sys/param.h>
#ifdef EXEC_PAGESIZE
#define getpagesize() EXEC_PAGESIZE
#else
#ifdef NBPG
#define getpagesize() NBPG * CLSIZE
#ifndef CLSIZE
#define CLSIZE 1
#endif /* no CLSIZE */
#else /* no NBPG */
#define getpagesize() NBPC
#endif /* no NBPG */
#endif /* no EXEC_PAGESIZE */
#endif /* not HAVE_GETPAGESIZE */

View File

@ -0,0 +1,164 @@
/* Main program for interactive testing. For maximum output, compile
this and regex.c with -DDEBUG. */
#include <stdio.h>
#include <sys/types.h>
#include "regex.h"
/* Don't bother to guess about <string.h> vs <strings.h>, etc. */
extern int strlen ();
#define BYTEWIDTH 8
extern void printchar ();
extern char upcase[];
static void scanstring ();
static void print_regs ();
int
main (argc, argv)
int argc;
char **argv;
{
int i;
struct re_pattern_buffer buf;
char fastmap[(1 << BYTEWIDTH)];
/* Allow a command argument to specify the style of syntax. You can
use the `syntax' program to decode integer syntax values. */
if (argc > 1)
re_set_syntax (atoi (argv[1]));
buf.allocated = 0;
buf.buffer = NULL;
buf.fastmap = fastmap;
buf.translate = upcase;
for (;;)
{
char pat[500], str[500];
struct re_registers regs;
/* Some C compilers don't like `char pat[500] = ""'. */
pat[0] = 0;
printf ("Pattern (%s) = ", pat);
gets (pat);
scanstring (pat);
if (feof (stdin))
{
putchar ('\n');
exit (0);
}
if (*pat)
{
re_compile_pattern (pat, strlen (pat), &buf);
re_compile_fastmap (&buf);
#ifdef DEBUG
print_compiled_pattern (&buf);
#endif
}
printf ("String = ");
gets (str); /* Now read the string to match against */
scanstring (str);
i = re_match (&buf, str, strlen (str), 0, &regs);
printf ("Match value %d.\t", i);
if (i >= 0)
print_regs (regs);
putchar ('\n');
i = re_search (&buf, str, strlen (str), 0, strlen (str), &regs);
printf ("Search value %d.\t", i);
if (i >= 0)
print_regs (regs);
putchar ('\n');
}
/* We never get here, but what the heck. */
return 0;
}
void
scanstring (s)
char *s;
{
char *write = s;
while (*s != '\0')
{
if (*s == '\\')
{
s++;
switch (*s)
{
case '\0':
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
*write = *s++ - '0';
if ('0' <= *s && *s <= '9')
{
*write = (*write << 3) + (*s++ - '0');
if ('0' <= *s && *s <= '9')
*write = (*write << 3) + (*s++ - '0');
}
write++;
break;
case 'n':
*write++ = '\n';
s++;
break;
case 't':
*write++ = '\t';
s++;
break;
default:
*write++ = *s++;
break;
}
}
else
*write++ = *s++;
}
*write++ = '\0';
}
/* Print REGS in human-readable form. */
void
print_regs (regs)
struct re_registers regs;
{
int i, end;
printf ("Registers: ");
if (regs.num_regs == 0 || regs.start[0] == -1)
{
printf ("(none)");
}
else
{
/* Find the last register pair that matched. */
for (end = regs.num_regs - 1; end >= 0; end--)
if (regs.start[end] != -1)
break;
printf ("[%d ", regs.start[0]);
for (i = 1; i <= end; i++)
printf ("(%d %d) ", regs.start[i], regs.end[i]);
printf ("%d]", regs.end[0]);
}
}

View File

@ -0,0 +1,49 @@
/* Main routine for running various tests. Meant only to be linked with
all the auxiliary test source files, with `test' undefined. */
#include "test.h"
test_type t = all_test;
/* Use this to run the tests we've thought of. */
int
main ()
{
switch (t)
{
case all_test:
test_regress ();
test_others ();
test_posix_basic ();
test_posix_extended ();
test_posix_interface ();
break;
case other_test:
test_others ();
break;
case posix_basic_test:
test_posix_basic ();
break;
case posix_extended_test:
test_posix_extended ();
break;
case posix_interface_test:
test_posix_interface ();
break;
case regress_test:
test_regress ();
break;
default:
fprintf (stderr, "Unknown test %d.\n", t);
}
return 0;
}

View File

@ -0,0 +1,47 @@
typedef struct {
unsigned *bits;
unsigned size;
} bits_list_type;
#define BYTEWIDTH 8
#define NULL 0
#define BITS_BLOCK_SIZE (sizeof (unsigned) * BYTEWIDTH)
#define BITS_BLOCK(position) ((position) / BITS_BLOCK_SIZE)
#define BITS_MASK(position) (1 << ((position) % BITS_BLOCK_SIZE))
static unsigned
init_bits_list (bits_list_ptr)
bits_list_type *bits_list_ptr;
{
bits_list_ptr->bits = NULL;
bits_list_ptr->bits = (unsigned *) malloc (sizeof (unsigned));
if (bits_list_ptr->bits == NULL)
return 0;
bits_list_ptr->bits[0] = (unsigned)0;
bits_list_ptr->size = BITS_BLOCK_SIZE;
return 1;
}
main()
{
bits_list_type dummy;
bits_list_type dummy_1;
bits_list_type dummy_2;
bits_list_type dummy_3;
init_bits_list (&dummy);
printf("init 1\n");
init_bits_list (&dummy_1);
printf("init 2\n");
init_bits_list (&dummy_2);
printf("init 3\n");
init_bits_list (&dummy_3);
printf("init 4\n");
}

View File

@ -0,0 +1,503 @@
/* other.c: test (not exhaustively) non-POSIX regular expressions. */
#include "test.h"
void
test_others ()
{
struct re_registers regs;
printf ("\nStarting non-POSIX tests.\n");
t = other_test;
test_should_match = true;
/* The big question: does the group participate in the match, or match
the empty string? */
re_set_syntax (RE_NO_BK_PARENS);
test_match ("(a*)*ab", "ab");
TEST_REGISTERS ("(a*)*ab", "ab", 0, 2, 0, 0, -1, -1);
test_match ("(a*)*", "");
TEST_REGISTERS ("(a*)*ab", "ab", 0, 0, 0, 0, -1, -1);
/* This tests finding the highest and lowest active registers. */
test_match ("(a(b)c(d(e)f)g)h(i(j)k(l(m)n)o)\\1\\2\\3\\4\\5\\6\\7\\8",
"abcdefghijklmnoabcdefgbdefeijklmnojlmnm");
/* Test that \< and \> match at the beginning and end of the string. */
test_match ("\\<abc\\>", "abc");
/* May as well test \` and \' while we're at it. */
test_match ("\\`abc\\'", "abc");
#if 0
/* Test backreferencing and the fastmap -- which doesn't work. */
test_fastmap ("(a)*\\1", "a", 0, 0);
#endif
/* But at least we shouldn't search improperly. */
test_search_return (-1, "(a)\\1", "");
re_set_syntax (RE_SYNTAX_EMACS);
MATCH_SELF("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
MATCH_SELF ("a^");
MATCH_SELF ("a^b");
MATCH_SELF ("$a");
MATCH_SELF ("a$b");
re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
test_match ("[\\^a]", "a");
test_match ("[\\^a]", "^");
/* These op characters should be ordinary if RE_CONTEXT_INVALID_OPS
isn't set. */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_BRACES | RE_INTERVALS
| RE_NO_BK_PARENS);
MATCH_SELF ("*");
test_match ("a|*", "*");
test_match ("(*)", "*");
MATCH_SELF ("+");
test_match ("a|+", "+");
test_match ("(+)", "+");
MATCH_SELF ("?");
test_match ("a|?", "?");
test_match ("(?)", "?");
MATCH_SELF ("{1}");
test_match ("a|{1}", "a");
test_match ("a|{1}", "{1}");
test_match ("({1})", "{1}");
test_match ("\\{", "{");
re_set_syntax (RE_LIMITED_OPS);
MATCH_SELF ("|");
MATCH_SELF ("a|");
MATCH_SELF ("a|");
MATCH_SELF ("a||");
MATCH_SELF ("a||");
MATCH_SELF ("(|)");
re_set_syntax (RE_SYNTAX_EMACS);
TEST_SEARCH ("^a", "b\na", 0, 3);
TEST_SEARCH ("b$", "b\na", 0, 3);
#if 0
/* Newline is no longer special for anchors (16 Sep 92). --karl */
test_match_2 ("a\n^b", "a", "\nb");
test_match_2 ("a$\nb", "a\n", "b");
#endif
/* Test grouping. */
re_set_syntax (RE_NO_BK_PARENS);
test_match ("()", "");
test_fastmap ("()", "", 0, 0);
TEST_REGISTERS ("()", "", 0, 0, 0, 0, -1, -1);
test_match ("((((((((()))))))))", "");
test_fastmap ("((((((((()))))))))", "", 0, 0);
test_match ("a()b", "ab");
TEST_REGISTERS ("a()b", "ab", 0, 2, 1, 1, -1, -1);
test_match ("(((((((((())))))))))", "");
test_fastmap ("(((((((((())))))))))", "", 0, 0);
test_match ("()*", "");
TEST_REGISTERS ("()*", "", 0, 0, 0, 0, -1, -1); /* empty string */
test_match ("(())*", "");
re_set_syntax (RE_CONTEXT_INDEP_OPS);
test_match ("*", "");
re_set_syntax (RE_INTERVALS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES);
test_match ("{1}", ""); /* Should remain an interval. */
MATCH_SELF ("{1"); /* Not a valid interval. */
re_set_syntax (RE_NEWLINE_ALT);
test_match ("a\nb", "a");
test_match ("a\nb", "b");
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
test_match ("^a", "a");
test_match ("(^a)", "a");
test_match ("(a|^b)", "b");
test_match ("a$", "a");
test_match ("(a$)", "a");
test_match ("a$|b", "a");
/* You should be able to have empty alternatives if RE_NO_EMPTY_ALTS
isn't set. */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
test_match ("|", "");
test_match ("^|a", "");
test_match ("^|a", "a");
test_match ("a|", "");
test_match ("a|", "a");
test_match ("a|$", "");
test_match ("a|$", "a");
test_match ("a||b", "a");
test_match ("a||b", "");
test_match ("a||b", "b");
test_match ("(|a)", "");
test_match ("(|a)", "a");
test_match ("(a|)", "");
test_match ("(a|)", "a");
TEST_SEARCH ("a|$", "xa", 0, 2);
TEST_SEARCH ("a|$", "x", 0, 1);
TEST_SEARCH ("$|b", "x", 0, 1);
TEST_SEARCH ("$|b", "xb", 0, 2);
TEST_SEARCH ("c(a|$)", "xca", 0, 3);
TEST_SEARCH ("c(a|$)", "xc", 0, 2);
TEST_SEARCH ("c($|b)", "xcb", 0, 3);
TEST_SEARCH ("c($|b)", "xc", 0, 2);
TEST_SEARCH ("c($|b$)", "xcb", 0, 3);
TEST_SEARCH ("c($|b$)", "xc", 0, 2);
TEST_SEARCH ("c(a$|$)", "xca", 0, 3);
TEST_SEARCH ("c(a$|$)", "xc", 0, 2);
TEST_SEARCH ("(a$|b$)|$", "x", 0, 1);
TEST_SEARCH ("(a$|b$)|$", "xa", 0, 2);
TEST_SEARCH ("(a$|b$)|$", "xb", 0, 2);
TEST_SEARCH ("(a$|$)|c$", "x", 0, 1);
TEST_SEARCH ("(a$|$)|c$", "xa", 0, 2);
TEST_SEARCH ("(a$|$)|c$", "xc", 0, 2);
TEST_SEARCH ("($|b$)|c$", "x", 0, 1);
TEST_SEARCH ("($|b$)|c$", "xb", 0, 2);
TEST_SEARCH ("($|b$)|c$", "xc", 0, 2);
TEST_SEARCH ("c$|(a$|$)", "x", 0, 1);
TEST_SEARCH ("c$|(a$|$)", "xa", 0, 2);
TEST_SEARCH ("c$|(a$|$)", "xc", 0, 2);
TEST_SEARCH ("c$|($|b$)", "x", 0, 1);
TEST_SEARCH ("c$|($|b$)", "xb", 0, 2);
TEST_SEARCH ("c$|($|b$)", "xc", 0, 2);
TEST_SEARCH ("$|(a$|b$)", "x", 0, 1);
TEST_SEARCH ("$|(a$|b$)", "xa", 0, 2);
TEST_SEARCH ("$|(a$|b$)", "xb", 0, 2);
TEST_SEARCH ("c(a$|b$)|$", "x", 0, 1);
TEST_SEARCH ("c(a$|b$)|$", "xca", 0, 3);
TEST_SEARCH ("c(a$|b$)|$", "xcb", 0, 3);
TEST_SEARCH ("c(a$|$)|d$", "xc", 0, 2);
TEST_SEARCH ("c(a$|$)|d$", "xca", 0, 3);
TEST_SEARCH ("c(a$|$)|d$", "xd", 0, 2);
TEST_SEARCH ("c($|b$)|d$", "xc", 0, 2);
TEST_SEARCH ("c($|b$)|d$", "xcb", 0, 3);
TEST_SEARCH ("c($|b$)|d$", "xd", 0, 2);
TEST_SEARCH ("d(c$|e((a$|$)))", "xdc", 0, 3);
TEST_SEARCH ("d(c$|e((a$|$)))", "xde", 0, 3);
TEST_SEARCH ("d(c$|e((a$|$)))", "xdea", 0, 4);
TEST_SEARCH ("d(c$|e(($|b$)))", "xdc", 0, 3);
TEST_SEARCH ("d(c$|e(($|b$)))", "xde", 0, 3);
TEST_SEARCH ("d(c$|e(($|b$)))", "xdeb", 0, 4);
TEST_SEARCH ("d($|e((a$|b$)))", "xd", 0, 2);
TEST_SEARCH ("d($|e((a$|b$)))", "xdea", 0, 4);
TEST_SEARCH ("d($|e((a$|b$)))", "xdeb", 0, 4);
TEST_SEARCH ("a(b$|c$)|$", "x", 0, 1);
TEST_SEARCH ("a(b$|c$)|$", "xab", 0, 3);
TEST_SEARCH ("a(b$|c$)|$", "xac", 0, 3);
TEST_SEARCH ("a(b$|$)|d$", "xa", 0, 2);
TEST_SEARCH ("a(b$|$)|d$", "xab", 0, 3);
TEST_SEARCH ("a(b$|$)|d$", "xd", 0, 2);
TEST_SEARCH ("a($|c$)|d$", "xa", 0, 2);
TEST_SEARCH ("a($|c$)|d$", "xac", 0, 3);
TEST_SEARCH ("a($|c$)|d$", "xd", 0, 2);
TEST_SEARCH ("d$|a(b$|$)", "xd", 0, 2);
TEST_SEARCH ("d$|a(b$|$)", "xa", 0, 2);
TEST_SEARCH ("d$|a(b$|$)", "xab", 0, 3);
TEST_SEARCH ("d$|a($|c$)", "xd", 0, 2);
TEST_SEARCH ("d$|a($|c$)", "xa", 0, 2);
TEST_SEARCH ("d$|a($|c$)", "xac", 0, 3);
TEST_SEARCH ("$|a(b$|c$)", "x", 0, 1);
TEST_SEARCH ("$|a(b$|c$)", "xab", 0, 3);
TEST_SEARCH ("$|a(b$|c$)", "xac", 0, 3);
TEST_SEARCH ("(a)(b$|c$)|d$", "xab", 0, 3);
TEST_SEARCH ("(a)(b$|c$)|d$", "xac", 0, 3);
TEST_SEARCH ("(a)(b$|c$)|d$", "xd", 0, 2);
TEST_SEARCH ("(a)(b$|$)|d$", "xa", 0, 2);
TEST_SEARCH ("(a)(b$|$)|d$", "xab", 0, 3);
TEST_SEARCH ("(a)(b$|$)|d$", "xd", 0, 2);
TEST_SEARCH ("(a)($|c$)|d$", "xa", 0, 2);
TEST_SEARCH ("(a)($|c$)|d$", "xac", 0, 3);
TEST_SEARCH ("(a)($|c$)|d$", "xd", 0, 2);
TEST_SEARCH ("d$|(a)(b$|$)", "xd", 0, 2);
TEST_SEARCH ("d$|(a)(b$|$)", "xa", 0, 2);
TEST_SEARCH ("d$|(a)(b$|$)", "xab", 0, 3);
TEST_SEARCH ("d$|(a)($|c$)", "xd", 0, 2);
TEST_SEARCH ("d$|(a)($|c$)", "xa", 0, 2);
TEST_SEARCH ("d$|(a)($|c$)", "xac", 0, 3);
TEST_SEARCH ("$|(a)(b$|c$)", "x", 0, 1);
TEST_SEARCH ("$|(a)(b$|c$)", "xab", 0, 3);
TEST_SEARCH ("$|(a)(b$|c$)", "xac", 0, 3);
TEST_SEARCH ("d$|(c$|(a$|$))", "x", 0, 1);
TEST_SEARCH ("d$|(c$|(a$|$))", "xd", 0, 2);
TEST_SEARCH ("d$|(c$|(a$|$))", "xc", 0, 2);
TEST_SEARCH ("d$|(c$|(a$|$))", "xa", 0, 2);
TEST_SEARCH ("d$|(c$|($|b$))", "x", 0, 1);
TEST_SEARCH ("d$|(c$|($|b$))", "xd", 0, 2);
TEST_SEARCH ("d$|(c$|($|b$))", "xc", 0, 2);
TEST_SEARCH ("d$|(c$|($|b$))", "xb", 0, 2);
TEST_SEARCH ("d$|($|(a$|b$))", "x", 0, 1);
TEST_SEARCH ("d$|($|(a$|b$))", "xd", 0, 2);
TEST_SEARCH ("d$|($|(a$|b$))", "xa", 0, 2);
TEST_SEARCH ("d$|($|(a$|b$))", "xb", 0, 2);
TEST_SEARCH ("$|(c$|(a$|b$))", "x", 0, 1);
TEST_SEARCH ("$|(c$|(a$|b$))", "xc", 0, 2);
TEST_SEARCH ("$|(c$|(a$|b$))", "xa", 0, 2);
TEST_SEARCH ("$|(c$|(a$|b$))", "xb", 0, 2);
TEST_SEARCH ("d$|c(a$|$)", "xd", 0, 2);
TEST_SEARCH ("d$|c(a$|$)", "xc", 0, 2);
TEST_SEARCH ("d$|c(a$|$)", "xca", 0, 3);
TEST_SEARCH ("d$|c($|b$)", "xd", 0, 2);
TEST_SEARCH ("d$|c($|b$)", "xc", 0, 2);
TEST_SEARCH ("d$|c($|b$)", "xcb", 0, 3);
TEST_SEARCH ("$|c(a$|b$)", "x", 0, 1);
TEST_SEARCH ("$|c(a$|b$)", "xca", 0, 3);
TEST_SEARCH ("$|c(a$|b$)", "xcb", 0, 3);
TEST_SEARCH ("e(d$|c((a$|$)))", "xed", 0, 3);
TEST_SEARCH ("e(d$|c((a$|$)))", "xec", 0, 3);
TEST_SEARCH ("e(d$|c((a$|$)))", "xeca", 0, 3);
TEST_SEARCH ("e(d$|c(($|b$)))", "xed", 0, 3);
TEST_SEARCH ("e(d$|c(($|b$)))", "xec", 0, 3);
TEST_SEARCH ("e(d$|c(($|b$)))", "xecb", 0, 4);
TEST_SEARCH ("e($|c((a$|b$)))", "xe", 0, 2);
TEST_SEARCH ("e($|c((a$|b$)))", "xeca", 0, 4);
TEST_SEARCH ("e($|c((a$|b$)))", "xecb", 0, 4);
TEST_SEARCH ("ed$|(c((a$|$)))", "xed", 0, 3);
TEST_SEARCH ("ed$|(c((a$|$)))", "xc", 0, 2);
TEST_SEARCH ("ed$|(c((a$|$)))", "xca", 0, 3);
TEST_SEARCH ("ed$|(c(($|b$)))", "xed", 0, 3);
TEST_SEARCH ("ed$|(c(($|b$)))", "xc", 0, 2);
TEST_SEARCH ("ed$|(c(($|b$)))", "xcb", 0, 3);
TEST_SEARCH ("$|(c((a$|b$)))", "x", 0, 1);
TEST_SEARCH ("$|(c((a$|b$)))", "xca", 0, 3);
TEST_SEARCH ("$|(c((a$|b$)))", "xcb", 0, 3);
TEST_SEARCH ("d$|($|(a|b)$)", "x", 0, 1);
TEST_SEARCH ("d$|($|(a|b)$)", "xa", 0, 2);
TEST_SEARCH ("d$|($|(a|b)$)", "xb", 0, 2);
TEST_SEARCH ("$|(c$|(a|b)$)", "x", 0, 1);
TEST_SEARCH ("$|(c$|(a|b)$)", "xc", 0, 2);
TEST_SEARCH ("$|(c$|(a|b)$)", "xa", 0, 2);
TEST_SEARCH ("$|(c$|(a|b)$)", "xb", 0, 2);
re_set_syntax (0);
test_match ("[^\n]", "a");
test_match ("[^a]", "\n");
TEST_SEARCH ("^a", "b\na", 0, 3);
TEST_SEARCH ("b$", "b\na", 0, 3);
test_case_fold ("[!-`]", "A");
test_case_fold ("[!-`]", "a");
re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_NO_BK_VBAR | RE_NO_BK_PARENS
| RE_NO_BK_BRACES | RE_INTERVALS);
valid_nonposix_pattern ("()^a");
valid_nonposix_pattern ("()\\1^a");
/* Per Cederqvist (cedar@lysator.liu.se) bug. */
re_set_syntax (RE_SYNTAX_EMACS);
/* One `a' before the \n and 638 a's after it. */
test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
/* No a's before the \n and 639 a's after it. */
test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
/* One `a' before the \n and 639 a's after it. */
test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
/* No a's before the \n and 640 a's after it. */
test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
TEST_SEARCH ("^(^a)", "ab", 0, 2);
TEST_SEARCH ("(a$)$", "ba", 0, 2);
test_match ("a|$b", "$b");
/* Mike's curiosity item. */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
test_all_registers ("(foo|foobar)(foo|bar)*\\1(foo|bar)*",
"foobarfoobar", "",
0, 12, 0, 3, 3, 6, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1);
/* Another one from Mike. */
test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");
/* And another. */
test_match("(foo|foobar)(bar|barfoo)?\\1", "foobarfoobar");
re_set_syntax (RE_NO_BK_PARENS | RE_INTERVALS | RE_NO_BK_VBAR
| RE_NO_BK_BRACES); /* xx get new ones from ext.*/
test_match ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "bb");
test_all_registers ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "", "bb",
0, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1);
test_match ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "b");
test_all_registers ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "", "b",
0, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1);
/* Valid anchoring. */
/* See generic_test.c and extended_test.c for more search
tests. xx Not sure all these tests are represented in the
search tests. */
re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
valid_nonposix_pattern
("(((((((((((((((((((((((((((((((((^a)))))))))))))))))))))))))))))))))");
valid_nonposix_pattern
("(((((((((((((((((((((((((((((((((a$)))))))))))))))))))))))))))))))))");
valid_nonposix_pattern ("\\b\\B\\<\\>\\`\\'^a");
valid_nonposix_pattern ("a$\\b\\B\\<\\>\\`\\'");
valid_nonposix_pattern ("(^a)");
valid_nonposix_pattern ("(a$)");
valid_nonposix_pattern ("(^a)b");
valid_nonposix_pattern ("b(a$)");
valid_nonposix_pattern ("(^a|^b)c");
valid_nonposix_pattern ("c(a$|b$)");
valid_nonposix_pattern ("(^a|^b)|^c");
valid_nonposix_pattern ("(a$|b$)|c$");
valid_nonposix_pattern ("^c|(^a|^b)");
valid_nonposix_pattern ("c$|(a$|b$)");
valid_nonposix_pattern ("(^a|^b)c|^d");
valid_nonposix_pattern ("c(a$|b$)|d$");
valid_nonposix_pattern ("(((^a|^b))c|^d)e");
valid_nonposix_pattern ("(c((a|b))|d)e$");
valid_nonposix_pattern ("^d(c|e((a|b)))");
valid_nonposix_pattern ("d(c$|e((a$|b$)))");
valid_nonposix_pattern ("(((^a|^b))c)|^de");
valid_nonposix_pattern ("(((a|b))c$)|de$");
valid_nonposix_pattern ("((a$)$)$");
valid_nonposix_pattern ("^(^(^a))");
valid_nonposix_pattern ("^de|^(c((a|b)))");
valid_nonposix_pattern ("^de|(^c((a|b)))");
valid_nonposix_pattern ("de$|(c((a|b)$))");
valid_nonposix_pattern ("de$|(c((a|b))$)");
valid_nonposix_pattern ("de$|(c((a|b)))$");
valid_nonposix_pattern ("^a(b|c)|^d");
valid_nonposix_pattern ("a(b$|c$)|d$");
valid_nonposix_pattern ("^d|^a(b|c)");
valid_nonposix_pattern ("d$|a(b$|c$)");
valid_nonposix_pattern ("^d|^(b|c)a");
valid_nonposix_pattern ("d$|(b|c)a$");
valid_nonposix_pattern ("^(a)(b|c)|^d");
valid_nonposix_pattern ("(a)(b|c)$|d$");
valid_nonposix_pattern ("(^a)(b|c)|^d");
valid_nonposix_pattern ("(a)(b$|c$)|d$");
valid_nonposix_pattern ("^d|^(b|c)(a)");
valid_nonposix_pattern ("d$|(b|c)(a)$");
valid_nonposix_pattern ("^d|(^b|^c)(a)");
valid_nonposix_pattern ("d$|(b|c)(a$)");
valid_nonposix_pattern ("^d|^(a)(b|c)");
valid_nonposix_pattern ("^d|(^a)(b|c)");
valid_nonposix_pattern ("d$|(a)(b$|c$)");
valid_nonposix_pattern ("((^a|^b)|^c)|^d");
valid_nonposix_pattern ("d$|(c$|(a$|b$))");
/* Tests shouldn't match. */
test_should_match = false;
/* Test that RE_CONTEXT_INVALID_OPS has precedence over
RE_CONTEXT_INDEP_OPS. */
re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_CONTEXT_INVALID_OPS
| RE_NO_BK_VBAR | RE_NO_BK_PARENS
| RE_NO_BK_BRACES | RE_INTERVALS);
INVALID_PATTERN ("*");
INVALID_PATTERN ("^*");
INVALID_PATTERN ("a|*");
INVALID_PATTERN ("(*)");
INVALID_PATTERN ("^+");
INVALID_PATTERN ("+");
INVALID_PATTERN ("a|+");
INVALID_PATTERN ("(+)");
INVALID_PATTERN ("^?");
INVALID_PATTERN ("?");
INVALID_PATTERN ("a|?");
INVALID_PATTERN ("(?)");
INVALID_PATTERN ("^{1}");
INVALID_PATTERN ("{1}");
INVALID_PATTERN ("a|{1}");
INVALID_PATTERN ("({1})");
#if 0
/* No longer have this syntax option -- POSIX says empty alternatives
are undefined as of draft 11.2. */
/* You can't have empty alternatives if RE_NO_EMPTY_ALTS is set. */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
INVALID_PATTERN ("|");
INVALID_PATTERN ("^|a");
INVALID_PATTERN ("a|");
INVALID_PATTERN ("a||");
INVALID_PATTERN ("a||b");
INVALID_PATTERN ("(|a)");
INVALID_PATTERN ("(a|)");
INVALID_PATTERN ("(a|)");
/* Test above with `\(' and `\)'. */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_EMPTY_ALTS);
INVALID_PATTERN ("\\(|a\\)");
INVALID_PATTERN ("\\(a|\\)");
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
INVALID_PATTERN ("(|)()$|d$");
#endif
/* Test grouping. */
test_match ("()", "a");
/* Test backslashed intervals that are CONTEXTly invalid if have
nothing on which to operate. */
re_set_syntax (RE_INTERVALS | RE_CONTEXT_INVALID_OPS);
INVALID_PATTERN ("\\{1\\}");
re_set_syntax (0);
test_match ("z-a", "a");
re_set_syntax (RE_BK_PLUS_QM);
INVALID_PATTERN ("a*\\");
re_set_syntax (0);
INVALID_PATTERN ("a*\\");
re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
INVALID_PATTERN ("[\\");
#if 0
/* Empty groups are always ok now. (13 Sep 92) */
re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_GROUPS);
INVALID_PATTERN ("(|)()$|d$");
#endif
printf ("\nFinished non-POSIX tests.\n");
}
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -0,0 +1,14 @@
void
printchar (c)
char c;
{
if (c < 040 || c >= 0177)
{
putchar ('\\');
putchar (((c >> 6) & 3) + '0');
putchar (((c >> 3) & 7) + '0');
putchar ((c & 7) + '0');
}
else
putchar (c);
}

View File

@ -0,0 +1,253 @@
/* psx-basic.c: Test POSIX basic regular expressions. */
#include "test.h"
void
test_posix_basic ()
{
/* Intervals can only match up to RE_DUP_MAX occurences of anything. */
char dup_max_plus_one[6];
sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);
printf ("\nStarting POSIX basic tests.\n");
t = posix_basic_test;
re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_BASIC);
test_posix_generic ();
printf ("\nContinuing POSIX basic tests.\n");
/* Grouping tests that are not the same. */
test_should_match = false;
invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("a)"));
test_should_match = true;
/* Special characters. */
MATCH_SELF ("*");
test_match ("\\(*\\)", "*");
test_match ("\\(^*\\)", "*");
test_match ("**", "***");
test_match ("***", "****");
MATCH_SELF ("{"); /* of extended... */
MATCH_SELF ("()"); /* also non-Posix. */
MATCH_SELF ("a+");
MATCH_SELF ("a?");
MATCH_SELF ("a|b");
MATCH_SELF ("a|"); /* No alternations, */
MATCH_SELF ("|a"); /* so OK if empty. */
MATCH_SELF ("a||");
test_match ("\\(|a\\)", "|a");
test_match ("\\(a|\\)", "a|");
test_match ("a\\+", "a+");
test_match ("a\\?", "a?");
test_match ("a\\|b", "a|b");
test_match ("^*", "*");
test_match ("^+", "+");
test_match ("^?", "?");
test_match ("^{", "{");
/* Valid subexpressions
(empty) in basic only. */
test_match ("\\(\\)", "");
test_match ("a\\(\\)", "a");
test_match ("\\(\\)b", "b");
test_match ("a\\(\\)b", "ab");
TEST_REGISTERS ("a\\(\\)b", "ab", 0, 2, 1, 1, -1, -1);
test_match ("\\(\\)*", "");
test_match ("\\(\\(\\)\\)*", "");
/* Valid back references. */
/* N.B.: back references to subexpressions that include a * are
undefined in the spec. The tests are in here to see if we handle
the situation consistently, but if it fails any of them, it doesn't
matter. */
test_match ("\\(\\)\\1", "");
TEST_REGISTERS ("\\(\\)\\1", "", 0, 0, 0, 0, -1, -1);
test_match ("\\(\\(\\)\\)\\(\\)\\2", "");
test_match ("\\(a\\)\\1", "aa");
TEST_REGISTERS ("\\(a\\)\\1", "aa", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a\\)\\1", "xaax", 1, 3, 1, 2, -1, -1);
test_match ("\\(\\(a\\)\\)\\1", "aa");
test_match ("\\(a\\)\\(b\\)\\2\\1", "abba");
test_match ("\\(a\\)*\\1", "aa");
TEST_REGISTERS ("\\(a\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a\\)*\\1", "xaax", 0, 0, -1, -1, -1, -1);
test_match ("\\(\\(a\\)\\2b\\)*", "aab");
TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "aab", 0, 3, 0, 3, 0, 1);
TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "xaabx", 0, 0, -1, -1, -1, -1);
test_match ("\\(a*\\)*\\1", "");
test_match ("\\(a*\\)*\\1", "aa");
TEST_REGISTERS ("\\(a*\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a*\\)*\\1", "xaax", 0, 0, 0, 0, -1, -1);
test_match ("\\(a*\\)*\\1", "");
test_match ("\\(a*\\)*\\1", "aa");
test_match ("\\(\\(a*\\)*\\)*\\1", "aa");
test_match ("\\(ab*\\)*\\1", "abab");
TEST_REGISTERS ("\\(ab*\\)*\\1", "abab", 0, 4, 0, 2, -1, -1);
TEST_REGISTERS ("\\(ab*\\)*\\1", "xababx", 0, 0, -1, -1, -1, -1);
test_match ("\\(a*\\)ab\\1", "aaba");
TEST_REGISTERS ("\\(a*\\)ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a*\\)ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
test_match ("\\(a*\\)*ab\\1", "aaba");
TEST_REGISTERS ("\\(a*\\)*ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a*\\)*ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
test_match ("\\(\\(a*\\)b\\)*\\2", "abb");
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "abb", 0, 3, 2, 3, 2, 2);
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xabbx", 0, 0, -1, -1, -1, -1);
/* Different from above. */
test_match ("\\(\\(a*\\)b*\\)*\\2", "aa");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aa", 0, 2, 0, 1, 0, 1);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaax", 0, 0, 0, 0, 0, 0);
test_match ("\\(\\(a*\\)b*\\)*\\2", "aba");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aba", 0, 3, 0, 2, 0, 1);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xabax", 0, 0, 0, 0, 0, 0);
test_match ("\\(\\(a*\\)b\\)*\\2", "aababa");
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "aababa", 0, 6, 3, 5, 3, 4);
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xaababax", 0, 0, -1, -1, -1, -1);
test_match ("\\(\\(a*\\)b*\\)*\\2", "aabaa");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabaa", 0, 5, 0, 3, 0, 2);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabaax", 0, 0, 0, 0, 0, 0);
test_match ("\\(\\(a*\\)b*\\)*\\2", "aabbaa");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabbaa", 0, 6, 0, 4, 0, 2);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabbaax", 0, 0, 0, 0, 0, 0);
test_match ("\\(\\(a*\\)b*\\)*\\2", "abaabaa");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "abaabaa", 0, 7, 2, 5, 2, 4);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaababaax", 0, 0, 0, 0, 0, 0);
test_match ("\\(\\(a*\\)b*\\)*a\\2", "aabaaa");
TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "aabaaa", 0, 6, 0, 3, 0, 2);
TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "xaabaax", 0, 0, -1, -1, -1, -1);
test_match ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa");
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa", 0, 6, 0, 3, 0, 2);
TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "xaabaaax", 1, 7, 1, 4, 1, 3);
test_match ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab");
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab", 0, 10, 2, 5, 2, 4);
/* We are matching the empty string here. */
TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "xabaabaaaabx", 0, 0, -1, -1, -1, -1);
test_match ("\\(a*b\\)\\1", "abab");
test_match ("\\(a\\)\\1\\1", "aaa");
test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdacdc");
test_match ("\\(a\\)\\1*", "aaa");
TEST_REGISTERS ("\\(a\\)\\1*", "aaa", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a\\)\\1*", "xaaax", 1, 4, 1, 2, -1, -1);
test_match ("\\(a\\)\\{1,3\\}b\\1", "aba");
TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "aba", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "xabax", 1, 4, 1, 2, -1, -1);
test_match ("\\(\\(a\\)\\2\\)*", "aaaa"); /* rms? */
TEST_REGISTERS ("\\(\\(a*b\\)\\2\\)*", "bbabab", 0, 6, 2, 6, 2, 4); /* rms? */
test_match ("\\(\\(a\\)\\1\\)*", "a1a1");
test_match ("\\(\\(a\\)\\2\\)\\1", "aaaa");
test_match ("\\(\\(a*\\)\\2\\)\\1", "aaaa");
TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "aaaa", 0, 4, 0, 2, 0, 1);
TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "xaaaax", 0, 0, 0, 0, 0, 0);
test_match ("\\{1\\}", "{1}");
test_match ("^\\{1\\}", "{1}");
test_match ("\\(a\\)\\1\\{1,2\\}", "aaa");
TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "aaa", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "xaaax", 1, 4, 1, 2, -1, -1);
/* Per POSIX D11.1 p. 109, leftmost longest match. */
test_match (PARENS_TO_OPS ("(.*).*\\1"), "abcabc");
/* Per POSIX D11.1, p. 125, leftmost longest match. */
test_match (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa");
TEST_REGISTERS (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa",
0, 8, 0, 1, -1, -1);
/* Anchors become ordinary, sometimes. */
MATCH_SELF ("a^");
MATCH_SELF ("$a");
MATCH_SELF ("$^");
test_fastmap ("$a^", "$", 0, 0);
test_match ("$^*", "$^^");
test_match ("\\($^\\)", "$^");
test_match ("$*", "$$");
/* xx -- known bug, solution pending test_match ("^^$", "^"); */
test_match ("$\\{0,\\}", "$$");
TEST_SEARCH ("^$*", "$$", 0, 2);
TEST_SEARCH ("^$\\{0,\\}", "$$", 0, 2);
MATCH_SELF ("2^10");
MATCH_SELF ("$HOME");
MATCH_SELF ("$1.35");
/* Basic regular expressions, continued; these don't match their strings. */
test_should_match = false;
invalid_pattern (REG_EESCAPE, "\\(a\\");
/* Invalid back references. */
test_match ("\\(a\\)\\1", "ab");
test_match ("\\(a\\)\\1\\1", "aab");
test_match ("\\(a\\)\\(b\\)\\2\\1", "abab");
test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdc");
test_match ("\\(a*b\\)\\1", "abaab");
test_match ("\\(a\\)\\1*", "aaaaaaaaaab");
test_match ("\\(\\(a\\)\\1\\)*", "aaa");
invalid_pattern (REG_ESUBREG, "\\1");
invalid_pattern (REG_ESUBREG, "\\(a\\)\\2");
test_match ("\\(\\(a\\)\\2\\)*", "abaa");
test_match ("\\(\\(a\\)\\1\\)*", "a");
test_match ("\\(\\(a\\)\\2\\)\\1", "abaa");
test_match ("\\(\\(a*\\)\\2\\)\\1", "abaa");
/* Invalid intervals. */
invalid_pattern (REG_EBRACE, "a\\{");
invalid_pattern (REG_BADBR, "a\\{-1");
invalid_pattern (REG_BADBR, concat ("a\\{", (char *)dup_max_plus_one));
invalid_pattern (REG_BADBR, concat (concat ("a\\{", (char *)dup_max_plus_one), ","));
invalid_pattern (REG_BADBR, "a\\{1,0");
invalid_pattern (REG_EBRACE, "a\\{1");
invalid_pattern (REG_EBRACE, "a\\{0,");
invalid_pattern (REG_EBRACE, "a\\{0,1");
invalid_pattern (REG_EBRACE, "a\\{0,1}");
printf ("\nFinished POSIX basic tests.\n");
}
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,336 @@
/* psx-generic.c: test POSIX re's independent of us using basic or
extended syntax. */
#include "test.h"
void
test_posix_generic ()
{
int omit_generic_tests = 0; /* reset in debugger to skip */
if (omit_generic_tests)
return;
/* Tests somewhat in the order of P1003.2. */
/* Both posix basic and extended; should match. */
printf ("\nStarting generic POSIX tests.\n");
test_grouping ();
test_intervals ();
test_should_match = true;
/* Ordinary characters. */
printf ("\nContinuing generic POSIX tests.\n");
MATCH_SELF ("");
test_fastmap ("", "", 0, 0);
test_fastmap_search ("", "", "", 0, 0, 2, 0, 0);
TEST_REGISTERS ("", "", 0, 0, -1, -1, -1, -1);
TEST_SEARCH ("", "", 0, 0);
TEST_SEARCH_2 ("", "", "", 0, 1, 0);
MATCH_SELF ("abc");
test_fastmap ("abc", "a", 0, 0);
TEST_REGISTERS ("abc", "abc", 0, 3, -1, -1, -1, -1);
TEST_REGISTERS ("abc", "xabcx", 1, 4, -1, -1, -1, -1);
test_match ("\\a","a");
test_match ("\\0", "0");
TEST_SEARCH ("a", "ab", 0, 2);
TEST_SEARCH ("b", "ab", 0, 2);
TEST_SEARCH ("a", "ab", 1, -2);
TEST_SEARCH_2 ("a", "a", "b", 0, 2, 2);
TEST_SEARCH_2 ("b", "a", "b", 0, 2, 2);
TEST_SEARCH_2 ("a", "a", "b", 1, -2, 2);
test_match ("\n", "\n");
test_match ("a\n", "a\n");
test_match ("\nb", "\nb");
test_match ("a\nb", "a\nb");
TEST_SEARCH ("b", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
/* Valid use of special characters. */
test_match ("a*", "aa");
test_fastmap ("a*", "a", 0, 0);
TEST_REGISTERS ("a*", "aa", 0, 2, -1, -1, -1, -1);
test_match ("a*b", "aab");
test_fastmap ("a*b", "ab", 0, 0);
test_match ("a*ab", "aab");
TEST_REGISTERS ("a*a", "aa", 0, 2, -1, -1, -1, -1);
TEST_REGISTERS ("a*a", "xaax", 1, 3, -1, -1, -1, -1);
test_match ("\\{", "{");
test_match ("\\^", "^");
test_match ("\\.", ".");
test_match ("\\*", "*");
test_match ("\\[", "[");
test_match ("\\$", "$");
test_match ("\\\\", "\\");
test_match ("ab*", "a");
test_match ("ab*", "abb");
/* Valid consecutive repetitions. */
test_match ("a**", "a");
/* Valid period. */
test_match (".", "a");
TEST_REGISTERS (".", "a", 0, 1, -1, -1, -1, -1);
test_match (".", "\004");
test_match (".", "\n");
/* Valid bracket expressions. */
test_match ("[ab]", "a");
test_match ("[ab]", "b");
test_fastmap ("[ab]", "ab", 0, 0);
TEST_REGISTERS ("[ab]", "a", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS ("[ab]", "xax", 1, 2, -1, -1, -1, -1);
test_fastmap ("[^ab]", "ab", 1, 1);
test_match ("[^ab]", "c");
test_match ("[^a]", "\n");
test_match ("[a]*a", "aa");
test_match ("[[]", "[");
test_match ("[]]", "]");
test_match ("[.]", ".");
test_match ("[*]", "*");
test_match ("[\\]", "\\");
test_match ("[\\(]", "(");
test_match ("[\\)]", ")");
test_match ("[^]]", "a");
test_match ("[a^]", "^");
test_match ("[a$]", "$");
test_match ("[]a]", "]");
test_match ("[a][]]", "a]");
test_match ("[\n]", "\n");
test_match ("[^a]", "\n");
test_match ("[a-]", "a");
TEST_REGISTERS ("\\`[ \t\n]*", " karl (Karl Berry)", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS ("[ \t\n]*\\'", " karl (Karl Berry)", 18, 18, -1, -1, -1, -1);
/* Collating, noncollating,
equivalence classes aren't
implemented yet. */
/* Character classes. */
test_match ("[:alpha:]", "p");
test_match ("[[:alpha:]]", "a");
test_match ("[[:alpha:]]", "z");
test_match ("[[:alpha:]]", "A");
test_match ("[[:alpha:]]", "Z");
test_match ("[[:upper:]]", "A");
test_match ("[[:upper:]]", "Z");
test_match ("[[:lower:]]", "a");
test_match ("[[:lower:]]", "z");
test_match ("[[:digit:]]", "0");
test_match ("[[:digit:]]", "9");
test_fastmap ("[[:digit:]]", "0123456789", 0, 0);
test_match ("[[:alnum:]]", "0");
test_match ("[[:alnum:]]", "9");
test_match ("[[:alnum:]]", "a");
test_match ("[[:alnum:]]", "z");
test_match ("[[:alnum:]]", "A");
test_match ("[[:alnum:]]", "Z");
test_match ("[[:xdigit:]]", "0");
test_match ("[[:xdigit:]]", "9");
test_match ("[[:xdigit:]]", "A");
test_match ("[[:xdigit:]]", "F");
test_match ("[[:xdigit:]]", "a");
test_match ("[[:xdigit:]]", "f");
test_match ("[[:space:]]", " ");
test_match ("[[:print:]]", " ");
test_match ("[[:print:]]", "~");
test_match ("[[:punct:]]", ",");
test_match ("[[:graph:]]", "!");
test_match ("[[:graph:]]", "~");
test_match ("[[:cntrl:]]", "\177");
test_match ("[[:digit:]a]", "a");
test_match ("[[:digit:]a]", "2");
test_match ("[a[:digit:]]", "a");
test_match ("[a[:digit:]]", "2");
test_match ("[[:]", "[");
test_match ("[:]", ":");
test_match ("[[:a]", "[");
test_match ("[[:alpha:a]", "[");
/* Valid ranges. */
test_match ("[a-a]", "a");
test_fastmap ("[a-a]", "a", 0, 0);
TEST_REGISTERS ("[a-a]", "xax", 1, 2, -1, -1, -1, -1);
test_match ("[a-z]", "z");
test_fastmap ("[a-z]", "abcdefghijklmnopqrstuvwxyz", 0, 0);
test_match ("[-a]", "-"); /* First */
test_match ("[-a]", "a");
test_match ("[a-]", "-"); /* Last */
test_match ("[a-]", "a");
test_match ("[--@]", "@"); /* First and starting point. */
test_match ("[%--a]", "%"); /* Ending point. */
test_match ("[%--a]", "-"); /* Ditto. */
test_match ("[a%--]", "%"); /* Both ending point and last. */
test_match ("[a%--]", "-");
test_match ("[%--a]", "a"); /* Ending point only. */
test_match ("[a-c-f]", "e"); /* Piggyback. */
test_match ("[)-+--/]", "*");
test_match ("[)-+--/]", ",");
test_match ("[)-+--/]", "/");
test_match ("[[:digit:]-]", "-");
/* Concatenation ????*/
test_match ("[ab][cd]", "ac");
test_fastmap ("[ab][cd]", "ab", 0, 0);
TEST_REGISTERS ("[ab][cd]", "ad", 0, 2, -1, -1, -1, -1);
TEST_REGISTERS ("[ab][cd]", "xadx", 1, 3, -1, -1, -1, -1);
/* Valid expression anchoring. */
test_match ("^a", "a");
test_fastmap ("^a", "a", 0, 0);
TEST_REGISTERS ("^a", "ax", 0, 1, -1, -1, -1, -1);
test_match ("^", "");
TEST_REGISTERS ("^", "", 0, 0, -1, -1, -1, -1);
test_match ("$", "");
TEST_REGISTERS ("$", "", 0, 0, -1, -1, -1, -1);
test_match ("a$", "a");
test_fastmap ("a$", "a", 0, 0);
TEST_REGISTERS ("a$", "xa", 1, 2, -1, -1, -1, -1);
test_match ("^ab$", "ab");
test_fastmap ("^ab$", "a", 0, 0);
TEST_REGISTERS ("^a$", "a", 0, 1, -1, -1, -1, -1);
test_fastmap ("^$", "", 0, 0);
test_match ("^$", "");
TEST_REGISTERS ("^$", "", 0, 0, -1, -1, -1, -1);
TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ab", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ba", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ab", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ba", 0, 2);
/* Two strings. */
test_match_2 ("ab", "a", "b");
TEST_REGISTERS_2 ("ab", "a", "b", 0, 2, -1, -1, -1, -1);
test_match_2 ("a", "", "a");
test_match_2 ("a", "a", "");
test_match_2 ("ab", "a", "b");
/* (start)pos. */
TEST_POSITIONED_MATCH ("b", "ab", 1);
/* mstop. */
TEST_TRUNCATED_MATCH ("a", "ab", 1);
/* Both basic and extended, continued; should not match. */
test_should_match = false;
/* Ordinary characters. */
test_match ("abc", "ab");
TEST_SEARCH ("c", "ab", 0, 2);
TEST_SEARCH ("c", "ab", 0, 2);
TEST_SEARCH ("c", "ab", 1, -2);
TEST_SEARCH ("c", "ab", 0, 10);
TEST_SEARCH ("c", "ab", 1, -10);
TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
TEST_SEARCH ("c", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
/* Invalid use of special characters. */
invalid_pattern (REG_EESCAPE, "\\");
invalid_pattern (REG_EESCAPE, "a\\");
invalid_pattern (REG_EESCAPE, "a*\\");
/* Invalid period. */
test_match (".", "");
/* Invalid bracket expressions. */
test_match ("[ab]", "c");
test_match ("[^b]", "b");
test_match ("[^]]", "]");
invalid_pattern (REG_EBRACK, "[");
invalid_pattern (REG_EBRACK, "[^");
invalid_pattern (REG_EBRACK, "[a");
invalid_pattern (REG_EBRACK, "[]");
invalid_pattern (REG_EBRACK, "[]a");
invalid_pattern (REG_EBRACK, "a[]a");
test_match ("[:alpha:]", "q"); /* Character classes. */
test_match ("[[:alpha:]]", "2");
test_match ("[[:upper:]]", "a");
test_match ("[[:lower:]]", "A");
test_match ("[[:digit:]]", "a");
test_match ("[[:alnum:]]", ":");
test_match ("[[:xdigit:]]", "g");
test_match ("[[:space:]]", "a");
test_match ("[[:print:]]", "\177");
test_match ("[[:punct:]]", "a");
test_match ("[[:graph:]]", " ");
test_match ("[[:cntrl:]]", "a");
invalid_pattern (REG_EBRACK, "[[:");
invalid_pattern (REG_EBRACK, "[[:alpha:");
invalid_pattern (REG_EBRACK, "[[:alpha:]");
invalid_pattern (REG_ECTYPE, "[[::]]");
invalid_pattern (REG_ECTYPE, "[[:a:]]");
invalid_pattern (REG_ECTYPE, "[[:alpo:]]");
invalid_pattern (REG_ECTYPE, "[[:a:]");
test_match ("[a-z]", "2"); /* Invalid ranges. */
test_match ("[^-a]", "-");
test_match ("[^a-]", "-");
test_match ("[)-+--/]", ".");
invalid_pattern (REG_ERANGE, "[z-a]"); /* Empty */
invalid_pattern (REG_ERANGE, "[a--]"); /* Empty */
invalid_pattern (REG_ERANGE, "[[:digit:]-9]");
invalid_pattern (REG_ERANGE, "[a-[:alpha:]]");
invalid_pattern (REG_ERANGE, "[a-");
invalid_pattern (REG_EBRACK, "[a-z");
test_match ("[ab][cd]", "ae"); /* Concatenation. */
test_match ("b*c", "b"); /* Star. */
/* Invalid anchoring. */
test_match ("^", "a");
test_match ("^a", "ba");
test_match ("$", "b");
test_match ("a$", "ab");
test_match ("^$", "a");
test_match ("^ab$", "a");
TEST_SEARCH ("^a", "b\na", 0, 3);
TEST_SEARCH ("b$", "b\na", 0, 3);
test_match_2 ("^a", "\n", "a");
test_match_2 ("a$", "a", "\n");
TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ba", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ba", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ab", 0, 2);
printf ("\nFinished generic POSIX tests.\n");
}
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -0,0 +1,440 @@
/* psx-group.c: test POSIX grouping, both basic and extended. */
#include "test.h"
void
test_grouping ()
{
printf ("\nStarting POSIX grouping tests.\n");
test_should_match = true;
test_fastmap (PARENS_TO_OPS ("(a)"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a)"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "a", 0, 1, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "xax", 1, 2, 1, 2, -1, -1);
test_match (PARENS_TO_OPS ("((a))"), "a");
test_fastmap (PARENS_TO_OPS ("((a))"), "a", 0, 0);
TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "a", 0, 1, 0, 1, 0, 1);
TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "xax", 1, 2, 1, 2, 1, 2);
test_fastmap (PARENS_TO_OPS ("(a)(b)"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a)(b)"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "ab", 0, 2, 0, 1, 1, 2);
TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "xabx", 1, 3, 1, 2, 2, 3);
test_all_registers (PARENS_TO_OPS ("((a)(b))"), "ab", "", 0, 2, 0, 2, 0, 1,
1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
/* Test that we simply ignore groups past the 255th. */
test_match (PARENS_TO_OPS ("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))"), "a");
/* Per POSIX D11.1, p. 125. */
test_fastmap (PARENS_TO_OPS ("(a)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "", 0, 0, -1, -1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "aa", 0, 2, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a*)"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "", 0, 0, 0, 0, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a*)"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "a", 0, 1, 0, 1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)b"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a*)b"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "b", 0, 1, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*)b"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "ab", 0, 2, 0, 1, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a*)b)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("((a*)b)*"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 2, 0, 2, 0, 1);
test_match (PARENS_TO_OPS ("((a*)b)*"), "abb");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abb", 0, 3, 2, 3, 2, 2);
test_match (PARENS_TO_OPS ("((a*)b)*"), "aabab");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "aabab", 0, 5, 3, 5, 3, 4);
test_match (PARENS_TO_OPS ("((a*)b)*"), "abbab");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abbab", 0, 5, 3, 5, 3, 4);
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("((a*)b)*"), "abaabaaaab");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abaabaaab", 0, 9, 5, 9, 5, 8);
test_fastmap (PARENS_TO_OPS ("(ab)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(ab)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(ab)*"), "abab");
TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "abab", 0, 4, 2, 4, -1, -1);
/* We match the empty string here. */
TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "xababx", 0, 0, -1, -1, -1, -1);
/* Per David A. Willcox. */
TEST_REGISTERS (PARENS_TO_OPS ("a(b*)c"), "ac", 0, 2, 1, 1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a)*b"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a)*b"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "b", 0, 1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(a)*b"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "ab", 0, 2, 0, 1, -1, -1);
test_match_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab");
TEST_REGISTERS_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab", 0, 3, 1, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a)*b"), "aab");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "aab", 0, 3, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a)*a"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a)*a"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*a"), "a", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, 0, 0);
test_match (PARENS_TO_OPS ("((a*))*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a*))*"), "", 0, 0, 0, 0, 0, 0);
test_match (PARENS_TO_OPS ("((a*))*"), "aa");
test_fastmap (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a*)*b"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "b", 0, 1, 0, 0, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xbx", 1, 2, 1, 1, -1, -1);
test_match (PARENS_TO_OPS ("(a*)*b"), "ab"); /* Per rms. */
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xabx", 1, 3, 1, 2, -1, -1);
/* Test register restores. */
test_match (PARENS_TO_OPS ("(a*)*b"), "aab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "aab", 0, 3, 0, 2, -1, -1);
TEST_REGISTERS_2 (PARENS_TO_OPS ("(a*)*b"), "a", "ab", 0, 3, 0, 2, -1, -1);
/* We are matching the empty string, with backtracking. */
test_fastmap (PARENS_TO_OPS ("(a*)a"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a*)a"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "a", 0, 1, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*)a"), "aa");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "aa", 0, 2, 0, 1, -1, -1);
/* We are matching the empty string, with backtracking. */
/*fails test_match (PARENS_TO_OPS ("(a*)*a"), "a"); */
test_match (PARENS_TO_OPS ("(a*)*a"), "aa");
/* Match the empty string. */
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "a", 0, 1, 0, 0, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xax", 1, 2, 1, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "aa", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xaax", 1, 3, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a)*ab"), "a", 0 , 0);
test_match (PARENS_TO_OPS ("(a)*ab"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "ab", 0, 2, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(a)*ab"), "aab");
TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "aab", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS("(a)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)ab"), "a", 0 , 0);
test_match (PARENS_TO_OPS ("(a*)ab"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "ab", 0, 2, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*)ab"), "aab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "aab", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "xaabx", 1, 4, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)*ab"), "a", 0 , 0);
test_match (PARENS_TO_OPS ("(a*)*ab"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "ab", 0, 2, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*)*ab"), "aab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "aab", 0, 3, 0, 1, -1, -1);
TEST_REGISTERS (PARENS_TO_OPS("(a*)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)*b*c"), "abc", 0, 0);
test_match (PARENS_TO_OPS ("(a*)*b*c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b*c"), "c", 0, 1, 0, 0, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a)*(ab)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a)*(ab)*"), "ab");
/* Register 1 doesn't match at all (vs. matching the empty string)
because of backtracking, hence -1's. */
TEST_REGISTERS (PARENS_TO_OPS ("(a)*(ab)*"), "ab", 0, 2, -1, -1, 0, 2);
test_match (PARENS_TO_OPS ("(a*)*(ab)*"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*(ab)*"), "ab", 0, 2, 0, 0, 0, 2);
test_fastmap (PARENS_TO_OPS ("(a*b)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a*b)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(a*b)*"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "b", 0, 1, 0, 1, -1, -1);
test_match (PARENS_TO_OPS ("(a*b)*"), "baab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "baab", 0, 4, 1, 4, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a*b*)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "a", 0, 1, 0, 1, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "ba");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ba", 0, 2, 1, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 2, 0, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "aa");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aa", 0, 2, 0, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "bb");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "bb", 0, 2, 0, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)*"), "aba");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aba", 0, 3, 2, 3, -1, -1);
test_match (PARENS_TO_OPS ("(a*b*)b"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)b"), "b", 0, 1, 0, 0, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a*)*(b*)*)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "");
test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "", "", 0, 0, 0, 0,
0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba");
/* Perhaps register 3 should be 3/3 here? Not sure if standard
specifies this. xx*/
test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba", "", 0, 3, 2, 3,
2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a*)(b*))*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a*)(b*))*"), "");
test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "", "", 0, 0, 0, 0,
0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
test_match (PARENS_TO_OPS ("((a*)(b*))*"), "aba");
test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "aba", "", 0, 3, 2, 3,
2, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a)*(b)*)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "");
test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "", "", 0, 0, 0, 0,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "aba");
test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "aba", "", 0, 3, 2, 3,
2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", 0, 0);
test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "");
test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "", "", 0, 0, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c");
test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", "", 0, 1, 0, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", 0, 0);
test_match (PARENS_TO_OPS ("c((a)*(b)*)*"), "c");
test_all_registers (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", "", 0, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "");
test_all_registers (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "", "", 0, 0, 0, 0,
0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
test_fastmap (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "c", 0, 0);
test_all_registers (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "", "", 0, 0, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a)*b)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a)*b)*"), "");
test_match (PARENS_TO_OPS ("((a)*b)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("((a)*b)*"), "abb");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abb", 0, 3, 2, 3, 0, 1); /*zz*/
test_match (PARENS_TO_OPS ("((a)*b)*"), "abbab");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abbab", 0, 5, 3, 5, 3, 4);
/* We match the empty string here. */
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(a*)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(a*)*"), "aa");
TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "aa", 0, 2, 0, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("((a*)*)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "", 0, 0, 0, 0, 0, 0);
test_match (PARENS_TO_OPS ("((a*)*)*"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 1, 0, 1, 0, 1);
test_fastmap (PARENS_TO_OPS ("(ab*)*"), "a", 0, 0);
test_match (PARENS_TO_OPS ("(ab*)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "", 0, 0, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(ab*)*"), "aa");
TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "aa", 0, 2, 1, 2, -1, -1);
test_fastmap (PARENS_TO_OPS ("(ab*)*c"), "ac", 0, 0);
test_match (PARENS_TO_OPS ("(ab*)*c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "c", 0, 1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(ab*)*c"), "abbac");
TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abbac", 0, 5, 3, 4, -1, -1);
test_match (PARENS_TO_OPS ("(ab*)*c"), "abac");
TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abac", 0, 4, 2, 3, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*b)*c"), "abc", 0, 0);
test_match (PARENS_TO_OPS ("(a*b)*c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "c", 0, 1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(a*b)*c"), "bbc");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "bbc", 0, 3, 1, 2, -1, -1);
test_match (PARENS_TO_OPS ("(a*b)*c"), "aababc");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aababc", 0, 6, 3, 5, -1, -1);
test_match (PARENS_TO_OPS ("(a*b)*c"), "aabaabc");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aabaabc", 0, 7, 3, 6, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a*)b*)"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a*)b*)"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "", 0, 0, 0, 0, 0, 0);
test_match (PARENS_TO_OPS ("((a*)b*)"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "a", 0, 1, 0, 1, 0, 1);
test_match (PARENS_TO_OPS ("((a*)b*)"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "b", 0, 1, 0, 1, 0, 0);
test_fastmap (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("((a)*b*)"), "");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "", 0, 0, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("((a)*b*)"), "a");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "a", 0, 1, 0, 1, 0, 1);
test_match (PARENS_TO_OPS ("((a)*b*)"), "b");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "b", 0, 1, 0, 1, -1, -1);
test_match (PARENS_TO_OPS ("((a)*b*)"), "ab");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 2, 0, 2, 0, 1);
test_fastmap (PARENS_TO_OPS ("((a*)b*)c"), "abc", 0, 0);
test_match (PARENS_TO_OPS ("((a*)b*)c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)c"), "c", 0, 1, 0, 0, 0, 0);
test_fastmap (PARENS_TO_OPS ("((a)*b*)c"), "abc", 0, 0);
test_match (PARENS_TO_OPS ("((a)*b*)c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)c"), "c", 0, 1, 0, 0, -1, -1);
test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(a*b*)*"), "");
TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
test_fastmap (PARENS_TO_OPS ("(((a*))((b*)))*"), "ab", 0, 0);
test_match (PARENS_TO_OPS ("(((a*))((b*)))*"), "");
test_all_registers (PARENS_TO_OPS ("(((a*))((b*)))*"), "", "", 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "abcde", 0, 0);
test_match (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "");
test_all_registers (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "", "", 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
test_fastmap (PARENS_TO_OPS ("((a)*b)*c"), "abc", 0, 0);
test_match (PARENS_TO_OPS ("((a)*b)*c"), "c");
TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*c"), "c", 0, 1, -1, -1, -1, -1);
test_match (PARENS_TO_OPS ("(ab)*"), "");
test_match (PARENS_TO_OPS ("((ab)*)"), "");
test_match (PARENS_TO_OPS ("(((ab)*))"), "");
test_match (PARENS_TO_OPS ("((((ab)*)))"), "");
test_match (PARENS_TO_OPS ("(((((ab)*))))"), "");
test_match (PARENS_TO_OPS ("((((((ab)*)))))"), "");
test_match (PARENS_TO_OPS ("(((((((ab)*))))))"), "");
test_match (PARENS_TO_OPS ("((((((((ab)*)))))))"), "");
test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
test_fastmap (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "a", 0, 0);
test_match (PARENS_TO_OPS ("((((((((((ab)*)))))))))"), "");
test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "", NULL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1);
test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab");
test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab", NULL,
0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 2, 4);
test_should_match = false;
invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("(a"));
test_match (PARENS_TO_OPS ("(a)"), "");
test_match (PARENS_TO_OPS ("((a))"), "b");
test_match (PARENS_TO_OPS ("(a)(b)"), "ac");
test_match (PARENS_TO_OPS ("(ab)*"), "acab");
test_match (PARENS_TO_OPS ("(a*)*b"), "c");
test_match (PARENS_TO_OPS ("(a*b)*"), "baa");
test_match (PARENS_TO_OPS ("(a*b)*"), "baabc");
test_match (PARENS_TO_OPS ("(a*b*)*"), "c");
test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "c");
test_match (PARENS_TO_OPS ("(a*)*"), "ab");
test_match (PARENS_TO_OPS ("((a*)*)*"), "ab");
test_match (PARENS_TO_OPS ("((a*)*)*"), "b");
test_match (PARENS_TO_OPS ("(ab*)*"), "abc");
test_match (PARENS_TO_OPS ("(ab*)*c"), "abbad");
test_match (PARENS_TO_OPS ("(a*c)*b"), "aacaacd");
test_match (PARENS_TO_OPS ("(a*)"), "b");
test_match (PARENS_TO_OPS ("((a*)b*)"), "c");
/* Expression anchoring. */
TEST_SEARCH (PARENS_TO_OPS ("(^b)"), "ab", 0, 2);
TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
printf ("\nFinished POSIX grouping tests.\n");
}

View File

@ -0,0 +1,624 @@
/* psx-interf.c: test POSIX interface. */
#include <string.h>
#include <assert.h>
#include "test.h"
#define ERROR_CODE_LENGTH 20
#define TEST_ERRBUF_SIZE 15
void test_compile ();
/* ANSWER should be at least ERROR_CODE_LENGTH long. */
static char *
get_error_string (error_code, answer)
int error_code;
char answer[];
{
switch (error_code)
{
case 0: strcpy (answer, "No error"); break;
case REG_NOMATCH: strcpy (answer, "REG_NOMATCH"); break;
case REG_BADPAT: strcpy (answer, "REG_BADPAT"); break;
case REG_EPAREN: strcpy (answer, "REG_EPAREN"); break;
case REG_ESPACE: strcpy (answer, "REG_ESPACE"); break;
case REG_ECOLLATE: strcpy (answer, "REG_ECOLLATE"); break;
case REG_ECTYPE: strcpy (answer, "REG_ECTYPE"); break;
case REG_EESCAPE: strcpy (answer, "REG_EESCAPE"); break;
case REG_ESUBREG: strcpy (answer, "REG_ESUBREG"); break;
case REG_EBRACK: strcpy (answer, "REG_EBRACK"); break;
case REG_EBRACE: strcpy (answer, "REG_EBRACE"); break;
case REG_BADBR: strcpy (answer, "REG_BADBR"); break;
case REG_ERANGE: strcpy (answer, "REG_ERANGE"); break;
case REG_BADRPT: strcpy (answer, "REG_BADRPT"); break;
case REG_EEND: strcpy (answer, "REG_EEND"); break;
default: strcpy (answer, "Bad error code");
}
return answer;
}
/* I don't think we actually need to initialize all these things.
--karl */
void
init_pattern_buffer (pattern_buffer_ptr)
regex_t *pattern_buffer_ptr;
{
pattern_buffer_ptr->buffer = NULL;
pattern_buffer_ptr->allocated = 0;
pattern_buffer_ptr->used = 0;
pattern_buffer_ptr->fastmap = NULL;
pattern_buffer_ptr->fastmap_accurate = 0;
pattern_buffer_ptr->translate = NULL;
pattern_buffer_ptr->can_be_null = 0;
pattern_buffer_ptr->re_nsub = 0;
pattern_buffer_ptr->no_sub = 0;
pattern_buffer_ptr->not_bol = 0;
pattern_buffer_ptr->not_eol = 0;
}
void
test_compile (valid_pattern, error_code_expected, pattern,
pattern_buffer_ptr, cflags)
unsigned valid_pattern;
int error_code_expected;
const char *pattern;
regex_t *pattern_buffer_ptr;
int cflags;
{
int error_code_returned;
boolean error = false;
char errbuf[TEST_ERRBUF_SIZE];
init_pattern_buffer (pattern_buffer_ptr);
error_code_returned = regcomp (pattern_buffer_ptr, pattern, cflags);
if (valid_pattern && error_code_returned)
{
printf ("\nShould have been a valid pattern but wasn't.\n");
regerror (error_code_returned, pattern_buffer_ptr, errbuf,
TEST_ERRBUF_SIZE);
printf ("%s", errbuf);
error = true;
}
if (!valid_pattern && !error_code_returned)
{
printf ("\n\nInvalid pattern compiled as valid:\n");
error = true;
}
if (error_code_returned != error_code_expected)
{
char expected_error_string[ERROR_CODE_LENGTH];
char returned_error_string[ERROR_CODE_LENGTH];
get_error_string (error_code_expected, expected_error_string),
get_error_string (error_code_returned, returned_error_string);
printf (" Expected error code %s but got `%s'.\n",
expected_error_string, returned_error_string);
error = true;
}
if (error)
print_pattern_info (pattern, pattern_buffer_ptr);
}
static void
test_nsub (sub_count, pattern, cflags)
unsigned sub_count;
char *pattern;
int cflags;
{
regex_t pattern_buffer;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
if (pattern_buffer.re_nsub != sub_count)
{
printf ("\nShould have counted %d subexpressions but counted %d \
instead.\n", sub_count, pattern_buffer.re_nsub);
}
regfree (&pattern_buffer);
}
static void
test_regcomp ()
{
regex_t pattern_buffer;
int cflags = 0;
printf ("\nStarting regcomp tests.\n");
cflags = 0;
test_compile (0, REG_ESUBREG, "\\(a\\)\\2", &pattern_buffer, cflags);
test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
test_compile (0, REG_BADBR, "a\\{-1\\}", &pattern_buffer, cflags);
test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
test_compile (0, REG_EBRACE, "a\\{1", &pattern_buffer, cflags);
cflags = REG_EXTENDED;
test_compile (0, REG_ECTYPE, "[[:alpo:]]", &pattern_buffer, cflags);
test_compile (0, REG_EESCAPE, "\\", &pattern_buffer, cflags);
test_compile (0, REG_EBRACK, "[a", &pattern_buffer, cflags);
test_compile (0, REG_EPAREN, "(", &pattern_buffer, cflags);
test_compile (0, REG_ERANGE, "[z-a]", &pattern_buffer, cflags);
test_nsub (1, "(a)", cflags);
test_nsub (2, "((a))", cflags);
test_nsub (2, "(a)(b)", cflags);
cflags = REG_EXTENDED | REG_NOSUB;
test_nsub (1, "(a)", cflags);
regfree (&pattern_buffer);
printf ("\nFinished regcomp tests.\n");
}
static void
fill_pmatch (pmatch, start0, end0, start1, end1, start2, end2)
regmatch_t pmatch[];
regoff_t start0, end0, start1, end1, start2, end2;
{
pmatch[0].rm_so = start0;
pmatch[0].rm_eo = end0;
pmatch[1].rm_so = start1;
pmatch[1].rm_eo = end1;
pmatch[2].rm_so = start2;
pmatch[2].rm_eo = end2;
}
static void
test_pmatch (pattern, string, nmatch, pmatch, correct_pmatch, cflags)
char *pattern;
char *string;
unsigned nmatch;
regmatch_t pmatch[];
regmatch_t correct_pmatch[];
int cflags;
{
regex_t pattern_buffer;
unsigned this_match;
int error_code_returned;
boolean found_nonmatch = false;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
error_code_returned = regexec (&pattern_buffer, string, nmatch, pmatch, 0);
if (error_code_returned == REG_NOMATCH)
printf ("Matching failed in test_pmatch.\n");
else
{
for (this_match = 0; this_match < nmatch; this_match++)
{
if (pmatch[this_match].rm_so != correct_pmatch[this_match].rm_so)
{
if (found_nonmatch == false)
printf ("\n");
printf ("Pmatch start %d wrong: was %d when should have \
been %d.\n", this_match, pmatch[this_match].rm_so,
correct_pmatch[this_match].rm_so);
found_nonmatch = true;
}
if (pmatch[this_match].rm_eo != correct_pmatch[this_match].rm_eo)
{
if (found_nonmatch == false)
printf ("\n");
printf ("Pmatch end %d wrong: was %d when should have been \
%d.\n", this_match, pmatch[this_match].rm_eo,
correct_pmatch[this_match].rm_eo);
found_nonmatch = true;
}
}
if (found_nonmatch)
{
printf (" The number of pmatches requested was: %d.\n", nmatch);
printf (" The string to match was: `%s'.\n", string);
print_pattern_info (pattern, &pattern_buffer);
}
} /* error_code_returned == REG_NOMATCH */
regfree (&pattern_buffer);
}
static void
test_eflags (must_match_bol, must_match_eol, pattern, string, cflags, eflags)
boolean must_match_bol;
boolean must_match_eol;
char *pattern;
char *string;
int cflags;
int eflags;
{
regex_t pattern_buffer;
int error_code_returned;
boolean was_error = false;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
error_code_returned = regexec (&pattern_buffer, string, 0, 0, eflags);
if (error_code_returned == REG_NOMATCH)
{
/* If wasn't true that both 1) the anchored part of the pattern
had to match this string and 2) this string was a proper
substring... */
if (!( (must_match_bol && (eflags & REG_NOTBOL))
|| (must_match_eol && (eflags & REG_NOTEOL)) ))
{
printf ("\nEflags test failed: didn't match when should have.\n");
was_error = true;
}
}
else /* We got a match. */
{
/* If wasn't true that either 1) the anchored part of the pattern
didn't have to match this string or 2) this string wasn't a
proper substring... */
if ((must_match_bol == (eflags & REG_NOTBOL))
|| (must_match_eol == (eflags & REG_NOTEOL)))
{
printf ("\nEflags test failed: matched when shouldn't have.\n");
was_error = true;
}
}
if (was_error)
{
printf (" The string to match was: `%s'.\n", string);
print_pattern_info (pattern, &pattern_buffer);
if (eflags & REG_NOTBOL)
printf (" The eflag REG_BOL was set.\n");
if (eflags & REG_NOTEOL)
printf (" The eflag REG_EOL was set.\n");
}
regfree (&pattern_buffer);
}
static void
test_ignore_case (should_match, pattern, string, cflags)
boolean should_match;
char *pattern;
char *string;
int cflags;
{
regex_t pattern_buffer;
int error_code_returned;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
if (should_match && error_code_returned == REG_NOMATCH)
{
printf ("\nIgnore-case test failed:\n");
printf (" The string to match was: `%s'.\n", string);
print_pattern_info (pattern, &pattern_buffer);
if (cflags & REG_ICASE)
printf (" The cflag REG_ICASE was set.\n");
}
regfree (&pattern_buffer);
}
static void
test_newline (should_match, pattern, string, cflags)
boolean should_match;
char *pattern;
char *string;
int cflags;
{
regex_t pattern_buffer;
int error_code_returned;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
if (should_match && error_code_returned == REG_NOMATCH)
{
printf ("\nNewline test failed:\n");
printf (" The string to match was: `%s'.\n", string);
print_pattern_info (pattern, &pattern_buffer);
if (cflags & REG_NEWLINE)
printf (" The cflag REG_NEWLINE was set.\n");
else
printf (" The cflag REG_NEWLINE wasn't set.\n");
}
regfree (&pattern_buffer);
}
static void
test_posix_match (should_match, pattern, string, cflags)
boolean should_match;
char *pattern;
char *string;
int cflags;
{
regex_t pattern_buffer;
int error_code_returned;
boolean was_error = false;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
if (should_match && error_code_returned == REG_NOMATCH)
{
printf ("\nShould have matched but didn't:\n");
was_error = true;
}
else if (!should_match && error_code_returned != REG_NOMATCH)
{
printf ("\nShould not have matched but did:\n");
was_error = true;
}
if (was_error)
{
printf (" The string to match was: `%s'.\n", string);
print_pattern_info (pattern, &pattern_buffer);
}
regfree (&pattern_buffer);
}
static void
test_regexec ()
{
regmatch_t pmatch[3];
regmatch_t correct_pmatch[3];
int cflags = 0;
int eflags = 0;
printf ("\nStarting regexec tests.\n");
cflags = REG_NOSUB; /* shouldn't look at any of pmatch. */
test_pmatch ("a", "a", 0, pmatch, correct_pmatch, cflags);
/* Ask for less `pmatch'es than there are pattern subexpressions.
(Shouldn't look at pmatch[2]. */
cflags = REG_EXTENDED;
fill_pmatch (correct_pmatch, 0, 1, 0, 1, 100, 101);
test_pmatch ("((a))", "a", 2, pmatch, correct_pmatch, cflags);
/* Ask for same number of `pmatch'es as there are pattern subexpressions. */
cflags = REG_EXTENDED;
fill_pmatch(correct_pmatch, 0, 1, 0, 1, -1, -1);
test_pmatch ("(a)", "a", 2, pmatch, correct_pmatch, cflags);
/* Ask for more `pmatch'es than there are pattern subexpressions. */
cflags = REG_EXTENDED;
fill_pmatch (correct_pmatch, 0, 1, -1, -1, -1, -1);
test_pmatch ("a", "a", 2, pmatch, correct_pmatch, cflags);
eflags = REG_NOTBOL;
test_eflags (true, false, "^a", "a", cflags, eflags);
test_eflags (true, false, "(^a)", "a", cflags, eflags);
test_eflags (true, false, "a|^b", "b", cflags, eflags);
test_eflags (true, false, "^b|a", "b", cflags, eflags);
eflags = REG_NOTEOL;
test_eflags (false, true, "a$", "a", cflags, eflags);
test_eflags (false, true, "(a$)", "a", cflags, eflags);
test_eflags (false, true, "a|b$", "b", cflags, eflags);
test_eflags (false, true, "b$|a", "b", cflags, eflags);
eflags = REG_NOTBOL | REG_NOTEOL;
test_eflags (true, true, "^a$", "a", cflags, eflags);
test_eflags (true, true, "(^a$)", "a", cflags, eflags);
test_eflags (true, true, "a|(^b$)", "b", cflags, eflags);
test_eflags (true, true, "(^b$)|a", "b", cflags, eflags);
cflags = REG_ICASE;
test_ignore_case (true, "a", "a", cflags);
test_ignore_case (true, "A", "A", cflags);
test_ignore_case (true, "A", "a", cflags);
test_ignore_case (true, "a", "A", cflags);
test_ignore_case (true, "@", "@", cflags);
test_ignore_case (true, "\\[", "[", cflags);
test_ignore_case (true, "`", "`", cflags);
test_ignore_case (true, "{", "{", cflags);
test_ignore_case (true, "[!-`]", "A", cflags);
test_ignore_case (true, "[!-`]", "a", cflags);
cflags = 0;
test_ignore_case (false, "a", "a", cflags);
test_ignore_case (false, "A", "A", cflags);
test_ignore_case (false, "A", "a", cflags);
test_ignore_case (false, "a", "A", cflags);
test_ignore_case (true, "@", "@", cflags);
test_ignore_case (true, "\\[", "[", cflags);
test_ignore_case (true, "`", "`", cflags);
test_ignore_case (true, "{", "{", cflags);
test_ignore_case (true, "[!-`]", "A", cflags);
test_ignore_case (false, "[!-`]", "a", cflags);
/* Test newline stuff. */
cflags = REG_EXTENDED | REG_NEWLINE;
test_newline (true, "\n", "\n", cflags);
test_newline (true, "a\n", "a\n", cflags);
test_newline (true, "\nb", "\nb", cflags);
test_newline (true, "a\nb", "a\nb", cflags);
test_newline (false, ".", "\n", cflags);
test_newline (false, "[^a]", "\n", cflags);
test_newline (true, "\n^a", "\na", cflags);
test_newline (true, "\n(^a|b)", "\na", cflags);
test_newline (true, "a$\n", "a\n", cflags);
test_newline (true, "(a$|b)\n", "a\n", cflags);
test_newline (true, "(a$|b|c)\n", "a\n", cflags);
test_newline (true, "((a$|b|c)$)\n", "a\n", cflags);
test_newline (true, "((a$|b|c)$)\n", "b\n", cflags);
test_newline (true, "(a$|b)\n|a\n", "a\n", cflags);
test_newline (true, "^a", "\na", cflags);
test_newline (true, "a$", "a\n", cflags);
/* Now test normal behavior. */
cflags = REG_EXTENDED;
test_newline (true, "\n", "\n", cflags);
test_newline (true, "a\n", "a\n", cflags);
test_newline (true, "\nb", "\nb", cflags);
test_newline (true, "a\nb", "a\nb", cflags);
test_newline (true, ".", "\n", cflags);
test_newline (true, "[^a]", "\n", cflags);
test_newline (false, "\n^a", "\na", cflags);
test_newline (false, "a$\n", "a\n", cflags);
test_newline (false, "^a", "\na", cflags);
test_newline (false, "a$", "a\n", cflags);
/* Test that matches whole string only. */
cflags = 0;
test_posix_match (true, "a", "a", cflags);
/* Tests that match substrings. */
test_posix_match (true, "a", "ab", cflags);
test_posix_match (true, "b", "ab", cflags);
/* Test that doesn't match. */
test_posix_match (false, "a", "b", cflags);
printf ("\nFinished regexec tests.\n");
}
static void
test_error_code_message (error_code, expected_error_message)
int error_code;
char *expected_error_message;
{
char returned_error_message[TEST_ERRBUF_SIZE];
char error_code_string[ERROR_CODE_LENGTH];
size_t expected_error_message_length = strlen (expected_error_message) + 1;
size_t returned_error_message_length = regerror (error_code, 0,
returned_error_message,
TEST_ERRBUF_SIZE);
if (returned_error_message_length != expected_error_message_length)
{
printf ("\n\n Testing returned error codes, with expected error \
message `%s':\n", expected_error_message);
printf ("\n\n and returned error message `%s':\n",
returned_error_message);
printf (" should have returned a length of %d but returned %d.\n",
expected_error_message_length, returned_error_message_length);
}
if (strncmp (expected_error_message, returned_error_message,
TEST_ERRBUF_SIZE - 1) != 0)
{
get_error_string (error_code, error_code_string),
printf ("\n\n With error code %s (%d), expected error message:\n",
error_code_string, error_code);
printf (" `%s'\n", expected_error_message);
printf (" but got:\n");
printf (" `%s'\n", returned_error_message);
}
}
static void
test_error_code_allocation (error_code, expected_error_message)
int error_code;
char *expected_error_message;
{
char *returned_error_message = NULL;
char error_code_string[ERROR_CODE_LENGTH];
size_t returned_error_message_length = regerror (error_code, 0,
returned_error_message,
(size_t)0);
returned_error_message = xmalloc (returned_error_message_length + 1);
regerror (error_code, 0, returned_error_message,
returned_error_message_length);
if (strcmp (expected_error_message, returned_error_message) != 0)
{
get_error_string (error_code, error_code_string),
printf ("\n\n Testing error code allocation,\n");
printf ("with error code %s (%d), expected error message:\n",
error_code_string, error_code);
printf (" `%s'\n", expected_error_message);
printf (" but got:\n");
printf (" `%s'\n", returned_error_message);
}
}
static void
test_regerror ()
{
test_error_code_message (REG_NOMATCH, "No match");
test_error_code_message (REG_BADPAT, "Invalid regular expression");
test_error_code_message (REG_ECOLLATE, "Invalid collation character");
test_error_code_message (REG_ECTYPE, "Invalid character class name");
test_error_code_message (REG_EESCAPE, "Trailing backslash");
test_error_code_message (REG_ESUBREG, "Invalid back reference");
test_error_code_message (REG_EBRACK, "Unmatched [ or [^");
test_error_code_message (REG_EPAREN, "Unmatched ( or \\(");
test_error_code_message (REG_EBRACE, "Unmatched \\{");
test_error_code_message (REG_BADBR, "Invalid content of \\{\\}");
test_error_code_message (REG_ERANGE, "Invalid range end");
test_error_code_message (REG_ESPACE, "Memory exhausted");
test_error_code_message (REG_BADRPT, "Invalid preceding regular expression");
test_error_code_message (REG_EEND, "Premature end of regular expression");
test_error_code_message (REG_ESIZE, "Regular expression too big");
test_error_code_allocation (REG_ERPAREN, "Unmatched ) or \\)");
}
void
test_posix_interface ()
{
printf ("\nStarting POSIX interface tests.\n");
t = posix_interface_test;
test_regcomp ();
test_regexec ();
test_regerror ();
printf ("\nFinished POSIX interface tests.\n");
}

View File

@ -0,0 +1,140 @@
/* psx-interv.c: test POSIX intervals, both basic and extended. */
#include "test.h"
void
test_intervals ()
{
printf ("\nStarting POSIX interval tests.\n");
test_should_match = true;
/* Valid intervals. */
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "abaab");
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "a", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")),
"abaab", 0, 5, 2, 5, -1, -1);
test_match (BRACES_TO_OPS ("a{0}"), "");
test_fastmap (BRACES_TO_OPS ("a{0}"), "", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "", 0, 0, -1, -1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "x", 0, 0, -1, -1, -1, -1);
test_match (BRACES_TO_OPS ("a{0,}"), "");
test_match (BRACES_TO_OPS ("a{0,}"), "a");
test_fastmap (BRACES_TO_OPS ("a{0,}"), "a", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "a", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "xax", 0, 0, -1, -1, -1, -1);
test_match (BRACES_TO_OPS ("a{1}"), "a");
test_match (BRACES_TO_OPS ("a{1,}"), "a");
test_match (BRACES_TO_OPS ("a{1,}"), "aa");
test_match (BRACES_TO_OPS ("a{0,0}"), "");
test_match (BRACES_TO_OPS ("a{0,1}"), "");
test_match (BRACES_TO_OPS ("a{0,1}"), "a");
test_match (BRACES_TO_OPS ("a{1,3}"), "a");
test_match (BRACES_TO_OPS ("a{1,3}"), "aa");
test_match (BRACES_TO_OPS ("a{1,3}"), "aaa");
TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "aaa", 0, 3, -1, -1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "xaaax", 1, 4, -1, -1, -1, -1);
test_match (BRACES_TO_OPS ("a{0,3}b"), "b");
test_match (BRACES_TO_OPS ("a{0,3}b"), "aaab");
test_fastmap (BRACES_TO_OPS ("a{0,3}b"), "ab", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "b", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "xbx", 1, 2, -1, -1, -1, -1);
test_match (BRACES_TO_OPS ("a{1,3}b"), "ab");
test_match (BRACES_TO_OPS ("a{1,3}b"), "aaab");
test_match (BRACES_TO_OPS ("ab{1,3}c"), "abbbc");
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b");
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b", 0, 1, -1, -1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 2, 0, 1, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "xabx", 1, 3, 1, 2, -1, -1);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "ab");
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab");
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab", 0, 4, 2, 3, -1, -1);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "xaaabx", 1, 5, 3, 4, -1, -1);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab");
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "ab", 0, 0);
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab", 0, 5, 4, 4, -1, -1);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "b");
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "aaab");
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "ab", 0, 0);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab");
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab", 0, 5, 0, 3, -1, -1);
test_match (BRACES_TO_OPS (".{0,3}b"), "b");
test_match (BRACES_TO_OPS (".{0,3}b"), "ab");
test_match (BRACES_TO_OPS ("[a]{0,3}b"), "b");
test_match (BRACES_TO_OPS ("[a]{0,3}b"), "aaab");
test_fastmap (BRACES_TO_OPS ("[a]{0,3}b"), "ab", 0, 0);
test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "bcdb");
test_match (BRACES_TO_OPS ("ab{0,3}c"), "abbbc");
test_match (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "123d");
test_fastmap (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "0123456789d", 0, 0);
test_match (BRACES_TO_OPS ("\\*{0,3}a"), "***a");
test_match (BRACES_TO_OPS (".{0,3}b"), "aaab");
test_match (BRACES_TO_OPS ("a{0,3}a"), "aaa");
/* Backtracking. */
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 0);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a");
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 1, -1, -1, -1, -1);
test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 0);
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa");
TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 2, -1, -1, -1, -1);
test_match (BRACES_TO_OPS ("a{2}*"), "");
test_match (BRACES_TO_OPS ("a{2}*"), "aa");
test_match (BRACES_TO_OPS ("a{1}*"), "");
test_match (BRACES_TO_OPS ("a{1}*"), "a");
test_match (BRACES_TO_OPS ("a{1}*"), "aa");
test_match (BRACES_TO_OPS ("a{1}{1}"), "a");
test_match (BRACES_TO_OPS ("a{1}{1}{1}"), "a");
test_match (BRACES_TO_OPS ("a{1}{1}{2}"), "aa");
test_match (BRACES_TO_OPS ("a{1}{1}*"), "");
test_match (BRACES_TO_OPS ("a{1}{1}*"), "a");
test_match (BRACES_TO_OPS ("a{1}{1}*"), "aa");
test_match (BRACES_TO_OPS ("a{1}{1}*"), "aaa");
test_match (BRACES_TO_OPS ("a{1}{2}"), "aa");
test_match (BRACES_TO_OPS ("a{2}{1}"), "aa");
test_should_match = false;
test_match (BRACES_TO_OPS ("a{0}"), "a");
test_match (BRACES_TO_OPS ("a{0,}"), "b");
test_match (BRACES_TO_OPS ("a{1}"), "");
test_match (BRACES_TO_OPS ("a{1}"), "aa");
test_match (BRACES_TO_OPS ("a{1,}"), "");
test_match (BRACES_TO_OPS ("a{1,}"), "b");
test_match (BRACES_TO_OPS ("a{0,0}"), "a");
test_match (BRACES_TO_OPS ("a{0,1}"), "aa");
test_match (BRACES_TO_OPS ("a{0,1}"), "b");
test_match (BRACES_TO_OPS ("a{1,3}"), "");
test_match (BRACES_TO_OPS ("a{1,3}"), "aaaa");
test_match (BRACES_TO_OPS ("a{1,3}"), "b");
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaaab");
test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "bb");
test_match (BRACES_TO_OPS ("[a]{0,3}"), "aaaa");
test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "ab");
test_match (BRACES_TO_OPS ("ab{0,3}c"), "abababc");
test_match (BRACES_TO_OPS ("[:alpha:]{0,3}d"), "123d");
test_match (BRACES_TO_OPS ("\\^{1,3}a"), "a");
test_match (BRACES_TO_OPS (".{0,3}b"), "aaaab");
printf ("\nFinished POSIX interval tests.\n");
}

View File

@ -0,0 +1,8 @@
/;..*$/s/;/;\
/g
/{ .*$/s/{/{\
/g
/ \?[^'] /s/?/?\
/g
/ : /s/:/:\
/g

View File

@ -0,0 +1,74 @@
/* Print which syntax bits are set. */
#include <sys/types.h>
#include <stdio.h>
#include "regex.h"
/* It's coincidental that these two are currently the same. */
#define LONGEST_BIT_NAME "RE_UNMATCHED_RIGHT_PAREN_ORD"
#define LAST_BIT RE_UNMATCHED_RIGHT_PAREN_ORD
/* Sum of above, when printed. Assigned in main. */
static unsigned longest;
static void
test_bit (syntax, bit, name)
reg_syntax_t syntax;
unsigned bit;
char *name;
{
char padding[100], test_str[100];
int padding_count;
sprintf (test_str, "%s (%d=0x%x)", name, bit, bit);
padding_count = longest - strlen (test_str);
padding[padding_count] = 0;
while (padding_count--)
{
padding[padding_count] = ' ';
}
printf ("%s%s (%d=0x%x): %c\n",
name, padding, bit, bit, syntax & bit ? 'y' : 'n');
}
/* Macro to abbreviate the constant arguments. */
#define TEST_BIT(bit) test_bit (syntax, bit, #bit)
int
main (argc, argv)
int argc;
char *argv[];
{
reg_syntax_t syntax;
char syntax_str[1000], test_str[100];
switch (argc)
{
case 1:
printf ("Syntax? ");
scanf ("%s", syntax_str);
break;
case 2:
strcpy (syntax_str, argv[1]);
break;
default:
fprintf (stderr, "Usage: syntax [syntax].\n");
exit (1);
}
sscanf (syntax_str, "%i", &syntax);
/* Figure out the longest name, so we can align the output nicely. */
sprintf (test_str, "%s (%d=0x%x)", LONGEST_BIT_NAME, LAST_BIT, LAST_BIT);
longest = strlen (test_str);
/* [[[replace with bit tests]]] */
return 0;
}

View File

@ -0,0 +1,782 @@
/* test.c: testing routines for regex.c. */
#include <assert.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
char *malloc ();
char *realloc ();
#endif
/* Just to be complete, we make both the system V/ANSI and the BSD
versions of the string functions available. */
#if USG || STDC_HEADERS
#include <string.h>
#define index strchr
#define rindex strrchr
#define bcmp(s1, s2, len) memcmp ((s1), (s2), (len))
#define bcopy(from, to, len) memcpy ((to), (from), (len))
#define bzero(s, len) memset ((s), 0, (len))
#else
#include <strings.h>
#define strchr index
#define strrchr rindex
#ifndef NEED_MEMORY_H
#define memcmp(s1, s2, n) bcmp ((s1), (s2), (n))
#define memcpy(to, from, len) bcopy ((from), (to), (len))
#endif
extern char *strtok ();
extern char *strstr ();
#endif /* not USG or STDC_HEADERS */
/* SunOS 4.1 declares memchr in <memory.h>, not <string.h>. I don't
understand why. */
#if NEED_MEMORY_H
#include <memory.h>
#endif
#include "test.h"
#define BYTEWIDTH 8
extern void print_partial_compiled_pattern ();
extern void print_compiled_pattern ();
extern void print_double_string ();
/* If nonzero, the results of every test are displayed. */
boolean verbose = false;
/* If nonzero, don't do register testing. */
boolean omit_register_tests = true;
/* Says whether the current test should match or fail to match. */
boolean test_should_match;
static void
set_all_registers (start0, end0, start1, end1,
start2, end2, start3, end3,
start4, end4, start5, end5,
start6, end6, start7, end7,
start8, end8, start9, end9, regs)
int start0; int end0; int start1; int end1;
int start2; int end2; int start3; int end3;
int start4; int end4; int start5; int end5;
int start6; int end6; int start7; int end7;
int start8; int end8; int start9; int end9;
struct re_registers *regs;
{
unsigned r;
regs->start[0] = start0; regs->end[0] = end0;
regs->start[1] = start1; regs->end[1] = end1;
regs->start[2] = start2; regs->end[2] = end2;
regs->start[3] = start3; regs->end[3] = end3;
regs->start[4] = start4; regs->end[4] = end4;
regs->start[5] = start5; regs->end[5] = end5;
regs->start[6] = start6; regs->end[6] = end6;
regs->start[7] = start7; regs->end[7] = end7;
regs->start[8] = start8; regs->end[8] = end8;
regs->start[9] = start9; regs->end[9] = end9;
for (r = 10; r < regs->num_regs; r++)
{
regs->start[r] = -1;
regs->end[r] = -1;
}
}
/* Return the concatenation of S1 and S2. This would be a prime place
to use varargs. */
char *
concat (s1, s2)
char *s1;
char *s2;
{
char *answer = xmalloc (strlen (s1) + strlen (s2) + 1);
strcpy (answer, s1);
strcat (answer, s2);
return answer;
}
#define OK_TO_SEARCH (nonconst_buf.fastmap_accurate && (str1 || str2))
/* We ignore the `can_be_null' argument. Should just be removed. */
void
general_test (pattern_should_be_valid, match_whole_string,
pat, str1, str2, start, range, end, correct_fastmap,
correct_regs, can_be_null)
unsigned pattern_should_be_valid;
unsigned match_whole_string;
const char *pat;
char *str1, *str2;
int start, range, end;
char *correct_fastmap;
struct re_registers *correct_regs;
int can_be_null;
{
struct re_pattern_buffer nonconst_buf;
struct re_pattern_buffer old_buf;
struct re_registers regs;
const char *r;
char fastmap[1 << BYTEWIDTH];
unsigned *regs_correct = NULL;
unsigned all_regs_correct = 1;
boolean fastmap_internal_error = false;
unsigned match = 0;
unsigned match_1 = 0;
unsigned match_2 = 0;
unsigned invalid_pattern = 0;
boolean internal_error_1 = false;
boolean internal_error_2 = false;
nonconst_buf.allocated = 8;
nonconst_buf.buffer = xmalloc (nonconst_buf.allocated);
nonconst_buf.fastmap = fastmap;
nonconst_buf.translate = 0;
assert (pat != NULL);
r = re_compile_pattern (pat, strlen (pat), &nonconst_buf);
/* Kludge: if we are doing POSIX testing, we really should have
called regcomp, not re_compile_pattern. As it happens, the only
way in which it matters is that re_compile_pattern sets the
newline/anchor field for matching (part of what happens when
REG_NEWLINE is given to regcomp). We have to undo that for POSIX
matching. */
if (t == posix_basic_test || t == posix_extended_test)
nonconst_buf.newline_anchor = 0;
invalid_pattern = r != NULL;
if (!r)
{
int r;
if (!pattern_should_be_valid)
printf ("\nShould have been an invalid pattern but wasn't:\n");
else
{
fastmap_internal_error = (re_compile_fastmap (&nonconst_buf) == -2);
if (correct_fastmap)
nonconst_buf.fastmap_accurate =
memcmp (nonconst_buf.fastmap, correct_fastmap, 1 << BYTEWIDTH)
== 0;
if (OK_TO_SEARCH)
{
old_buf = nonconst_buf;
old_buf.buffer = (unsigned char *) xmalloc (nonconst_buf.used);
memcpy (old_buf.buffer, nonconst_buf.buffer, nonconst_buf.used);
/* If only one string is null, call re_match or re_search,
which is what the user would probably do. */
if (str1 == NULL && str2 != NULL
|| str2 == NULL && str1 != NULL)
{
char *the_str = str1 == NULL ? str2 : str1;
match_1
= match_whole_string
? (r = re_match (&nonconst_buf, the_str,
strlen (the_str), start, &regs))
== strlen (the_str)
: (r = re_search (&nonconst_buf,
the_str, strlen (the_str),
start, range, &regs))
>= 0;
if (r == -2)
internal_error_1 = true;
}
else
match_1 = 1;
/* Also call with re_match_2 or re_search_2, as they might
do this. (Also can check calling with either string1
or string2 or both null.) */
if (match_whole_string)
{
r = re_match_2 (&nonconst_buf,
str1, SAFE_STRLEN (str1),
str2, SAFE_STRLEN (str2),
start, &regs, end);
match_2 = r == SAFE_STRLEN (str1) + SAFE_STRLEN (str2);
}
else
{
r = re_search_2 (&nonconst_buf,
str1, SAFE_STRLEN (str1),
str2, SAFE_STRLEN (str2),
start, range, &regs, end);
match_2 = r >= 0;
}
if (r == -2)
internal_error_2 = true;
match = match_1 & match_2;
if (correct_regs)
{
unsigned reg;
if (regs_correct != NULL)
free (regs_correct);
regs_correct
= (unsigned *) xmalloc (regs.num_regs * sizeof (unsigned));
for (reg = 0;
reg < regs.num_regs && reg < correct_regs->num_regs;
reg++)
{
regs_correct[reg]
= (regs.start[reg] == correct_regs->start[reg]
&& regs.end[reg] == correct_regs->end[reg])
#ifdef EMPTY_REGS_CONFUSED
/* There is confusion in the standard about
the registers in some patterns which can
match either the empty string or not match.
For example, in `((a*))*' against the empty
string, the two registers can either match
the empty string (be 0/0), or not match
(because of the outer *) (be -1/-1). (Or
one can do one and one can do the other.) */
|| (regs.start[reg] == -1 && regs.end[reg] == -1
&& correct_regs->start[reg]
== correct_regs->end[reg])
#endif
;
all_regs_correct &= regs_correct[reg];
}
}
} /* OK_TO_SEARCH */
}
}
if (fastmap_internal_error)
printf ("\n\nInternal error in re_compile_fastmap:");
if (internal_error_1)
{
if (!fastmap_internal_error)
printf ("\n");
printf ("\nInternal error in re_match or re_search:");
}
if (internal_error_2)
{
if (!internal_error_1)
printf ("\n");
printf ("\nInternal error in re_match_2 or re_search_2:");
}
if ((OK_TO_SEARCH && ((match && !test_should_match)
|| (!match && test_should_match))
|| (correct_regs && !all_regs_correct))
|| !nonconst_buf.fastmap_accurate
|| invalid_pattern
|| !pattern_should_be_valid
|| internal_error_1 || internal_error_2
|| verbose)
{
if (OK_TO_SEARCH && match && !test_should_match)
{
printf ("\n\nMatched but shouldn't have:\n");
if (match_1)
printf ("The single match/search succeeded.\n");
if (match_2)
printf ("The double match/search succeeded.\n");
}
else if (OK_TO_SEARCH && !match && test_should_match)
{
printf ("\n\nDidn't match but should have:\n");
if (!match_1)
printf ("The single match/search failed.\n");
if (!match_2)
printf ("The double match/search failed.\n");
}
else if (invalid_pattern && pattern_should_be_valid)
printf ("\n\nInvalid pattern (%s):\n", r);
else if (!nonconst_buf.fastmap_accurate && pattern_should_be_valid)
printf ("\n\nIncorrect fastmap:\n");
else if (OK_TO_SEARCH && correct_regs && !all_regs_correct)
printf ("\n\nNot all registers were correct:\n");
else if (verbose)
printf ("\n\nTest was OK:\n");
if ((!(invalid_pattern && !pattern_should_be_valid)) || verbose)
printf (" Pattern: `%s'.\n", pat);
if (pattern_should_be_valid || verbose
|| internal_error_1 || internal_error_2)
{
printf(" Strings: ");
printf ("`%s' and ", str1 == NULL ? "NULL" : str1);
printf ("`%s'.\n", str2 == NULL ? "NULL" : str2);
if ((OK_TO_SEARCH || verbose || internal_error_1 || internal_error_2)
&& !invalid_pattern)
{
if (memcmp (old_buf.buffer, nonconst_buf.buffer,
nonconst_buf.used) != 0
&& !invalid_pattern)
{
printf(" (%s)\n", r ? r : "Valid regular expression");
printf ("\n Compiled pattern before matching: ");
print_compiled_pattern (&old_buf);
printf ("\n Compiled pattern after matching: ");
}
else
printf ("\n Compiled pattern: ");
print_compiled_pattern (&nonconst_buf);
}
if (correct_fastmap && (!nonconst_buf.fastmap_accurate || verbose))
{
printf ("\n The fastmap should have been: ");
print_fastmap (correct_fastmap);
printf ("\n Fastmap: ");
print_fastmap (fastmap);
printf ("\n Compiled pattern before matching: ");
print_compiled_pattern (&nonconst_buf);
}
if ((!all_regs_correct || verbose) && correct_regs)
{
unsigned this_reg;
printf ("\n Incorrect registers:");
for (this_reg = 0; this_reg < regs.num_regs; this_reg++)
{
if (!regs_correct[this_reg])
{
printf ("\n Register %d's start was %2d. ", this_reg,
regs.start[this_reg]);
printf ("\tIt should have been %d.\n",
correct_regs->start[this_reg]);
printf (" Register %d's end was %2d. ", this_reg,
regs.end[this_reg]);
printf ("\tIt should have been %d.\n",
correct_regs->end[this_reg]);
}
}
}
}
}
if (nonconst_buf.buffer != NULL)
free (nonconst_buf.buffer);
if (OK_TO_SEARCH)
{
free (old_buf.buffer);
if (correct_regs)
free (regs_correct);
}
nonconst_buf.buffer = old_buf.buffer = NULL;
regs_correct = NULL;
regs.start = regs.end = NULL;
} /* general_test */
void
test_search_return (match_start_wanted, pattern, string)
int match_start_wanted;
const char *pattern;
char *string;
{
struct re_pattern_buffer buf;
char fastmap[1 << BYTEWIDTH];
const char *compile_return;
int match_start;
static num_times_called = 0;
num_times_called++;
buf.allocated = 1;
buf.buffer = xmalloc (buf.allocated);
assert (pattern != NULL);
buf.translate = 0;
compile_return = re_compile_pattern (pattern, strlen (pattern), &buf);
if (compile_return)
{
printf ("\n\nInvalid pattern in test_match_start:\n");
printf ("%s\n", compile_return);
}
else
{
buf.fastmap = fastmap;
match_start = re_search (&buf, string, strlen (string),
0, strlen (string), 0);
if (match_start != match_start_wanted)
printf ("\nWanted search to start at %d but started at %d.\n",
match_start, match_start_wanted);
}
free (buf.buffer);
buf.buffer = NULL;
}
#define SET_FASTMAP() \
{ \
unsigned this_char; \
\
memset (correct_fastmap, invert, (1 << BYTEWIDTH)); \
\
for (this_char = 0; this_char < strlen (fastmap_string); this_char++)\
correct_fastmap[fastmap_string[this_char]] = !invert; \
correct_fastmap['\n'] = match_newline; \
}
void
test_fastmap (pat, fastmap_string, invert, match_newline)
const char *pat;
char *fastmap_string;
unsigned invert;
unsigned match_newline;
{
char correct_fastmap[(1 << BYTEWIDTH)];
SET_FASTMAP ();
general_test (1, 0, pat, NULL, NULL, -1, 0, -1, correct_fastmap, 0, -1);
}
void
test_fastmap_search (pat, str, fastmap_string, invert, match_newline,
can_be_null, start0, end0)
const char *pat;
char *str;
char *fastmap_string;
unsigned invert;
unsigned match_newline;
int can_be_null;
int start0;
int end0;
{
char correct_fastmap[(1 << BYTEWIDTH)];
struct re_registers correct_regs;
correct_regs.num_regs = RE_NREGS;
correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
set_all_registers (start0, end0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, &correct_regs);
SET_FASTMAP ();
general_test (1, 0, pat, str, NULL, 0, SAFE_STRLEN (str), SAFE_STRLEN (str),
correct_fastmap, &correct_regs, can_be_null);
free (correct_regs.start);
free (correct_regs.end);
}
void
test_all_registers (pat, str1, str2,
start0, end0, start1, end1,
start2, end2, start3, end3,
start4, end4, start5, end5,
start6, end6, start7, end7,
start8, end8, start9, end9)
char *pat; char *str1; char *str2;
int start0; int end0; int start1; int end1;
int start2; int end2; int start3; int end3;
int start4; int end4; int start5; int end5;
int start6; int end6; int start7; int end7;
int start8; int end8; int start9; int end9;
{
struct re_registers correct_regs;
if (omit_register_tests) return;
correct_regs.num_regs = RE_NREGS;
correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
set_all_registers (start0, end0, start1, end1, start2, end2, start3, end3,
start4, end4, start5, end5, start6, end6, start7, end7,
start8, end8, start9, end9, &correct_regs);
general_test (1, 0, pat, str1, str2, 0,
SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
NULL, &correct_regs, -1);
free (correct_regs.start);
free (correct_regs.end);
}
void
invalid_pattern (error_code_expected, pattern)
int error_code_expected;
char *pattern;
{
regex_t pattern_buffer;
int cflags
= re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
|| re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
? REG_EXTENDED : 0;
test_compile (0, error_code_expected, pattern, &pattern_buffer, cflags);
}
void
valid_pattern (pattern)
char *pattern;
{
regex_t pattern_buffer;
int cflags
= re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
|| re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
? REG_EXTENDED : 0;
test_compile (1, 0, pattern, &pattern_buffer, cflags);
}
char *
delimiters_to_ops (source, left_delimiter, right_delimiter)
char *source;
char left_delimiter;
char right_delimiter;
{
static char *answer = NULL;
char *tmp = NULL;
boolean double_size = false;
unsigned source_char;
unsigned answer_char = 0;
assert (source != NULL);
switch (left_delimiter)
{
case '(': if (!(re_syntax_options & RE_NO_BK_PARENS))
double_size = true;
break;
case '{': if (!(re_syntax_options & RE_NO_BK_BRACES))
double_size = true;
break;
default: printf ("Found strange delimiter %c in delimiter_to_ops.\n",
left_delimiter);
printf ("The source was `%s'\n", source);
exit (0);
}
if (answer == source)
{
tmp = (char *) xmalloc (strlen (source) + 1);
strcpy (tmp, source);
source = tmp;
}
if (answer)
{
free (answer);
answer = NULL;
}
answer = (char *) xmalloc ((double_size
? strlen (source) << 1
: strlen (source))
+ 1);
if (!double_size)
strcpy (answer, source);
else
{
for (source_char = 0; source_char < strlen (source); source_char++)
{
if (source[source_char] == left_delimiter
|| source[source_char] == right_delimiter)
answer[answer_char++] = '\\';
answer[answer_char++] = source[source_char];
}
answer[answer_char] = 0;
}
return answer;
}
void
print_pattern_info (pattern, pattern_buffer_ptr)
const char *pattern;
regex_t *pattern_buffer_ptr;
{
printf (" Pattern: `%s'.\n", pattern);
printf (" Compiled pattern: ");
print_compiled_pattern (pattern_buffer_ptr);
}
void
valid_nonposix_pattern (pattern)
char *pattern;
{
struct re_pattern_buffer nonconst_buf;
nonconst_buf.allocated = 0;
nonconst_buf.buffer = NULL;
nonconst_buf.translate = NULL;
assert (pattern != NULL);
if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
{
printf ("Couldn't compile the pattern.\n");
print_pattern_info (pattern, &nonconst_buf);
}
}
void
compile_and_print_pattern (pattern)
char *pattern;
{
struct re_pattern_buffer nonconst_buf;
nonconst_buf.allocated = 0;
nonconst_buf.buffer = NULL;
if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
printf ("Couldn't compile the pattern.\n");
print_pattern_info (pattern, &nonconst_buf);
}
void
test_case_fold (pattern, string)
const char *pattern;
char* string;
{
struct re_pattern_buffer nonconst_buf;
const char *ret;
init_pattern_buffer (&nonconst_buf);
nonconst_buf.translate = upcase;
assert (pattern != NULL);
ret = re_compile_pattern (pattern, strlen (pattern), &nonconst_buf);
if (ret)
{
printf ("\nShould have been a valid pattern but wasn't.\n");
print_pattern_info (pattern, &nonconst_buf);
}
else
{
if (test_should_match
&& re_match (&nonconst_buf, string, strlen (string), 0, 0)
!= strlen (string))
{
printf ("Match failed for case fold.\n");
printf (" Pattern: `%s'.\n", pattern);
printf (" String: `%s'.\n", string == NULL ? "NULL" : string);
}
}
}
void
test_match_n_times (n, pattern, string)
unsigned n;
char* pattern;
char* string;
{
struct re_pattern_buffer buf;
const char *r;
unsigned match = 0;
unsigned this_match;
buf.allocated = 0;
buf.buffer = NULL;
buf.translate = 0;
assert (pattern != NULL);
r = re_compile_pattern (pattern, strlen (pattern), &buf);
if (r)
{
printf ("Didn't compile.\n");
printf (" Pattern: %s.\n", pattern);
}
else
{
for (this_match = 1; this_match <= n; this_match++)
match = (re_match (&buf, string, strlen (string),
0, 0)
== strlen (string));
if (match && !test_should_match)
printf ("\n\nMatched but shouldn't have:\n");
else if (!match && test_should_match)
printf ("\n\nDidn't match but should have:\n");
if ((match && !test_should_match) || (!match && test_should_match))
{
printf(" The string to match was: ");
if (string)
printf ("`%s' and ", string);
else
printf ("`'");
printf (" Pattern: %s.\n", pattern);
printf (" Compiled pattern: %s.\n", pattern);
print_compiled_pattern (&buf);
}
}
}
void
test_match_2 (pat, str1, str2)
const char *pat;
char *str1;
char *str2;
{
general_test (1, 1, pat, str1, str2, 0, 1,
SAFE_STRLEN (str1) + SAFE_STRLEN (str2), NULL, 0, -1);
}
void
test_match (pat, str)
const char *pat;
char *str;
{
test_match_2 (pat, str, NULL);
test_match_2 (pat, NULL, str);
}

View File

@ -0,0 +1,141 @@
/* test.h: for Regex testing. */
#ifndef TEST_H
#define TEST_H
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include "regex.h"
/* A strlen that works even on a null pointer. */
#define SAFE_STRLEN(s) (s == NULL ? 0 : strlen (s))
typedef enum { false = 0, true = 1 } boolean;
extern boolean test_should_match;
extern boolean omit_register_tests;
extern void *xmalloc ();
/* Defined in upcase.c. */
extern char upcase[];
typedef enum
{
all_test,
other_test,
posix_basic_test,
posix_extended_test,
posix_interface_test,
regress_test
} test_type;
extern test_type t;
#if __STDC__
extern char *concat (char *, char *);
extern void general_test (unsigned pattern_should_be_valid,
unsigned match_whole_string,
const char *pat, char *str1, char *str2,
int start, int range, int end,
char *correct_fastmap,
struct re_registers *correct_regs, int can_be_null);
extern void init_pattern_buffer (regex_t *pattern_buffer_ptr);
extern void test_compile (unsigned valid_pattern, int error_code_expected,
const char *pattern, regex_t *pattern_buffer_ptr,
int cflags);
extern char *delimiter_to_ops (char *source, char left_delimiter,
char right_delimiter);
extern void test_search_return (int, const char *, char *);
extern void test_berk_search (const char *pattern, char *string);
extern void test_fastmap (const char *pat, char *fastmap_string, unsigned invert,
unsigned match_newline);
extern void test_fastmap_search (const char *pat, char *str, char *fastmap_string,
unsigned invert, unsigned match_newline,
int can_be_null, int start0, int end0);
extern void test_all_registers (char *pat, char *str1, char *str2,
int start0, int end0, int start1, int end1,
int start2, int end2, int start3, int end3,
int start4, int end4, int start5, int end5,
int start6, int end6, int start7, int end7,
int start8, int end8, int start9, int end9);
extern void print_pattern_info (const char *pattern, regex_t *pattern_buffer_ptr);
extern void compile_and_print_pattern (char *pattern);
extern void test_case_fold (const char *pattern, char* string);
extern void test_posix_generic ();
extern void test_grouping ();
extern void invalid_pattern (int error_code_expected, char *pattern);
extern void valid_nonposix_pattern (char *pattern);
extern void valid_pattern (char *pattern);
extern void test_match_2 (const char *pat, char *str1, char *str2);
extern void test_match (const char *pat, char *str);
#endif /* __STDC__ */
#define TEST_REGISTERS_2(pat, str1, str2, start0, end0, start1, end1, start2, end2)\
if (!omit_register_tests) \
test_all_registers (pat, str1, str2, start0, end0, start1, end1, \
start2, end2, -1, -1, -1, -1, -1, -1, -1, -1,\
-1, -1, -1, -1, -1, -1) \
#define TEST_REGISTERS(pat, str, start0, end0, start1, end1, start2, end2) \
TEST_REGISTERS_2 (pat, str, NULL, start0, end0, start1, end1, start2, end2)\
#define BRACES_TO_OPS(string) ((char *) delimiters_to_ops (string, '{', '}'))
#define PARENS_TO_OPS(string) ((char *) delimiters_to_ops (string, '(', ')'))
#define INVALID_PATTERN(pat) \
general_test (0, 0, pat, NULL, NULL, -1, 0, -1, NULL, 0, -1)
#define MATCH_SELF(p) test_match (p, p)
#define TEST_POSITIONED_MATCH(pat, str, start) \
general_test (1, 0, pat, str, NULL, start, 1, SAFE_STRLEN (str), \
NULL, 0, -1)
#define TEST_TRUNCATED_MATCH(pat, str, end) \
general_test (1, 0, pat, str, NULL, 0, 1, end, NULL, 0, -1)
#define TEST_SEARCH_2(pat, str1, str2, start, range, one_past_end) \
general_test (1, 0, pat, str1, str2, start, range, one_past_end, \
NULL, 0, -1)
#define TEST_SEARCH(pat, str, start, range) \
{ \
TEST_SEARCH_2 (pat, str, NULL, start, range, SAFE_STRLEN (str)); \
TEST_SEARCH_2 (pat, NULL, str, start, range, SAFE_STRLEN (str)); \
}
#endif /* TEST_H */
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -0,0 +1,464 @@
/* tregress.c: reported bugs. The `t' just makes the filename not have
a common prefix with `regex.c', so completion works better. */
#include "test.h"
boolean pause_at_error = true;
char *
itoa (i)
int i;
{
char *a = xmalloc (21); /* sign + 19 digits (enough for 64 bits) + null */
sprintf (a, "%d", i);
return a;
}
static void
simple_fail (routine, pat, buf, str, ret)
const char *routine;
const char *pat;
struct re_pattern_buffer *buf;
const char *str;
char *ret;
{
fprintf (stderr, "Failed %s (return = %s).\n", routine, ret);
if (str && *str) fprintf (stderr, " String = %s\n", str);
fprintf (stderr, " Pattern = %s\n", pat);
print_compiled_pattern (buf);
if (pause_at_error)
{
fprintf (stderr, "RET to continue: ");
(void) getchar ();
}
}
/* Abbreviate the most common calls. */
static void
simple_compile (pat, buf)
const char *pat;
struct re_pattern_buffer *buf;
{
const char *ret = re_compile_pattern (pat, strlen (pat), buf);
if (ret != NULL) simple_fail ("compile", pat, buf, NULL, ret);
}
static void
simple_fastmap (pat)
const char *pat;
{
struct re_pattern_buffer buf;
char fastmap[256];
int ret;
buf.allocated = 0;
buf.buffer = buf.translate = NULL;
buf.fastmap = fastmap;
simple_compile (pat, &buf);
ret = re_compile_fastmap (&buf);
if (ret != 0) simple_fail ("fastmap compile", pat, &buf, NULL, itoa (ret));
}
#define SIMPLE_MATCH(pat, str) do_match (pat, str, strlen (str))
#define SIMPLE_NONMATCH(pat, str) do_match (pat, str, -1)
static void
do_match (pat, str, expected)
const char *pat, *str;
int expected;
{
int ret;
unsigned len;
struct re_pattern_buffer buf;
buf.allocated = 0;
buf.buffer = buf.translate = buf.fastmap = NULL;
simple_compile (pat, &buf);
len = strlen (str);
ret = re_match_2 (&buf, NULL, 0, str, len, 0, NULL, len);
if (ret != expected) simple_fail ("match", pat, &buf, str, itoa (ret));
}
static void
simple_search (pat, str, correct_startpos)
const char *pat, *str;
int correct_startpos;
{
int ret;
unsigned len;
struct re_pattern_buffer buf;
buf.allocated = 0;
buf.buffer = buf.translate = buf.fastmap = NULL;
simple_compile (pat, &buf);
len = strlen (str);
ret = re_search_2 (&buf, NULL, 0, str, len, 0, len, NULL, len);
if (ret != correct_startpos)
simple_fail ("match", pat, &buf, str, itoa (ret));
}
/* Past bugs people have reported. */
void
test_regress ()
{
extern char upcase[];
struct re_pattern_buffer buf;
unsigned len;
struct re_registers regs;
int ret;
char *fastmap = xmalloc (256);
buf.translate = NULL;
buf.fastmap = NULL;
buf.allocated = 0;
buf.buffer = NULL;
printf ("\nStarting regression tests.\n");
t = regress_test;
test_should_match = true;
re_set_syntax (RE_SYNTAX_EMACS);
/* enami@sys.ptg.sony.co.jp 10 Nov 92 15:19:02 JST */
buf.translate = upcase;
SIMPLE_MATCH ("[A-[]", "A");
buf.translate = NULL;
/* meyering@cs.utexas.edu Nov 6 22:34:41 1992 */
simple_search ("\\w+", "a", 0);
/* jimb@occs.cs.oberlin.edu 10 Sep 92 00:42:33 */
buf.translate = upcase;
SIMPLE_MATCH ("[\001-\377]", "\001");
SIMPLE_MATCH ("[\001-\377]", "a");
SIMPLE_MATCH ("[\001-\377]", "\377");
buf.translate = NULL;
/* mike@skinner.cs.uoregon.edu 1 Sep 92 01:45:22 */
SIMPLE_MATCH ("^^$", "^");
/* pclink@qld.tne.oz.au Sep 7 22:42:36 1992 */
re_set_syntax (RE_INTERVALS);
SIMPLE_MATCH ("^a\\{3\\}$", "aaa");
SIMPLE_NONMATCH ("^a\\{3\\}$", "aa");
re_set_syntax (RE_SYNTAX_EMACS);
/* pclink@qld.tne.oz.au, 31 Aug 92. (conjecture) */
re_set_syntax (RE_INTERVALS);
simple_search ("a\\{1,3\\}b", "aaab", 0);
simple_search ("a\\{1,3\\}b", "aaaab", 1);
re_set_syntax (RE_SYNTAX_EMACS);
/* trq@dionysos.thphys.ox.ac.uk, 31 Aug 92. (simplified) */
simple_fastmap ("^.*\n[ ]*");
/* wind!greg@plains.NoDak.edu, 25 Aug 92. (simplified) */
re_set_syntax (RE_INTERVALS);
SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}", "xN0000");
SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}$", "systemxN0000");
SIMPLE_MATCH ("\\([a-zA-Z]*\\).\\{5\\}$", "systemxN0000");
re_set_syntax (RE_SYNTAX_EMACS);
/* jimb, 18 Aug 92. Don't use \000, so `strlen' (in our testing
routines) will work. (This still tickles the bug jimb reported.) */
SIMPLE_MATCH ("[\001-\377]", "\001");
SIMPLE_MATCH ("[\001-\377]", "a");
SIMPLE_MATCH ("[\001-\377]", "\377");
/* jimb, 13 Aug 92. */
SIMPLE_MATCH ("[\001-\177]", "\177");
/* Tests based on bwoelfel's below. */
SIMPLE_MATCH ("\\(a\\|ab\\)*", "aab");
SIMPLE_MATCH ("\\(a\\|ab\\)+", "aab");
SIMPLE_MATCH ("\\(a*\\|ab\\)+", "aab");
SIMPLE_MATCH ("\\(a+\\|ab\\)+", "aab");
SIMPLE_MATCH ("\\(a?\\|ab\\)+", "aab");
/* bwoelfel@widget.seas.upenn.edu, 25 Jul 92. */
SIMPLE_MATCH ("^\\([ab]+\\|bc\\)+", "abc");
/* jla, 3 Jul 92. Core dump in re_search_2. */
buf.fastmap = fastmap;
buf.translate = upcase;
#define DATEDUMP_PATTERN " *[0-9]*:"
if (re_compile_pattern (DATEDUMP_PATTERN, strlen (DATEDUMP_PATTERN), &buf)
!= NULL)
printf ("date dump compile failed.\n");
regs.num_regs = 0;
regs.start = regs.end = NULL;
if (re_search_2 (&buf, NULL, 0, "Thu Jul 2 18:34:18 1992",
24, 3, 21, &regs, 24) != 10)
printf ("date dump search failed.\n");
buf.fastmap = 0;
buf.translate = 0;
/* rms, 4 Jul 1992. Pattern is much slower in Emacs 19. Fastmap
should be only a backslash. */
#define BEGINEND_PATTERN "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)"
test_fastmap (BEGINEND_PATTERN, "\\", false, 0);
/* kaoru@is.s.u-tokyo.ac.jp, 27 Jun 1992. Code for [a-z] (in regex.c)
should translate the whole set. */
buf.translate = upcase;
#define CASE_SET_PATTERN "[ -`]"
if (re_compile_pattern (CASE_SET_PATTERN, strlen (CASE_SET_PATTERN), &buf)
!= NULL)
printf ("case set compile failed.\n");
if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
printf ("case set match failed.\n");
#define CASE_SET_PATTERN2 "[`-|]"
if (re_compile_pattern (CASE_SET_PATTERN2, strlen (CASE_SET_PATTERN2), &buf)
!= NULL)
printf ("case set2 compile failed.\n");
if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
printf ("case set2 match failed.\n");
buf.translate = NULL;
/* jimb, 27 Jun 92. Problems with gaps in the string. */
#define GAP_PATTERN "x.*y.*z"
if (re_compile_pattern (GAP_PATTERN, strlen (GAP_PATTERN), &buf) != NULL)
printf ("gap didn't compile.\n");
if (re_match_2 (&buf, "x-", 2, "y-z-", 4, 0, NULL, 6) != 5)
printf ("gap match failed.\n");
/* jimb, 19 Jun 92. Since `beginning of word' matches at the
beginning of the string, then searching ought to find it there.
If `re_compile_fastmap' is not called, then it works ok. */
buf.fastmap = fastmap;
#define BOW_BEG_PATTERN "\\<"
if (re_compile_pattern (BOW_BEG_PATTERN, strlen (BOW_BEG_PATTERN), &buf)
!= NULL)
printf ("begword-begstring didn't compile.\n");
if (re_search (&buf, "foo", 3, 0, 3, NULL) != 0)
printf ("begword-begstring search failed.\n");
/* Same bug report, different null-matching pattern. */
#define EMPTY_ANCHOR_PATTERN "^$"
if (re_compile_pattern (EMPTY_ANCHOR_PATTERN, strlen (EMPTY_ANCHOR_PATTERN),
&buf) != NULL)
printf ("empty anchor didn't compile.\n");
if (re_search (&buf, "foo\n\nbar", 8, 0, 8, NULL) != 4)
printf ("empty anchor search failed.\n");
/* jimb@occs.cs.oberlin.edu, 21 Apr 92. After we first allocate
registers for a particular re_pattern_buffer, we might have to
reallocate more registers on subsequent calls -- and we should be
reusing the same memory. */
#define ALLOC_REG_PATTERN "\\(abc\\)"
free (buf.fastmap);
buf.fastmap = 0;
if (re_compile_pattern (ALLOC_REG_PATTERN, strlen (ALLOC_REG_PATTERN), &buf)
!= NULL)
printf ("register allocation didn't compile.\n");
if (re_match (&buf, "abc", 3, 0, &regs) != 3)
printf ("register allocation didn't match.\n");
if (regs.start[1] != 0 || regs.end[1] != 3)
printf ("register allocation reg #1 wrong.\n");
{
int *old_regstart = regs.start;
int *old_regend = regs.end;
if (re_match (&buf, "abc", 3, 0, &regs) != 3)
printf ("register reallocation didn't match.\n");
if (regs.start[1] != 0 || regs.end[1] != 3
|| old_regstart[1] != 0 || old_regend[1] != 3
|| regs.start != old_regstart || regs.end != old_regend)
printf ("register reallocation registers wrong.\n");
}
/* jskudlarek@std.MENTORG.COM, 21 Apr 92 (string-match). */
#define JSKUD_PATTERN "[^/]+\\(/[^/.]+\\)?/[0-9]+$"
if (re_compile_pattern (JSKUD_PATTERN, strlen (JSKUD_PATTERN), &buf) != NULL)
printf ("jskud test didn't compile.\n");
if (re_search (&buf, "a/1", 3, 0, 3, &regs) != 0)
printf ("jskud test didn't match.\n");
if (regs.start[1] != -1 || regs.end[1] != -1)
printf ("jskud test, reg #1 wrong.\n");
/* jla's bug (with string-match), 5 Feb 92. */
TEST_SEARCH ("\\`[ \t\n]*", "jla@challenger (Joseph Arceneaux)", 0, 100);
/* jwz@lucid.com, 8 March 1992 (re-search-forward). (His is the
second.) These are not supposed to match. */
#if 0
/* This one fails quickly, because we can change the maybe_pop_jump
from the + to a pop_failure_pop, because of the c's. */
TEST_SEARCH ("^\\(To\\|CC\\):\\([^c]*\\)+co",
"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
Cc: eb@thalidomide, jlm@thalidomide\n\
Subject: Re: so is this really as horrible an idea as it seems to me?\n\
In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
References: <9203080736.AA05869@thalidomide.lucid>\n\
<9203081900.AA24794@titanic.lucid>", 0, 5000);
/* This one takes a long, long time to complete, because we have to
keep the failure points around because we might backtrack. */
TEST_SEARCH ("^\\(To\\|CC\\):\\(.*\n.*\\)+co",
/* "X-Windows: The joke that kills.\n\
FCC: /u/jwz/VM/inbox\n\
From: Jamie Zawinski <jwz@lucid.com>\n\ */
"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
Cc: eb@thalidomide, jlm@thalidomide\n\
Subject: Re: so is this really as horrible an idea as it seems to me?\n\
In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
References: <9203080736.AA05869@thalidomide.lucid>\n\
<9203081900.AA24794@titanic.lucid>", 0, 5000);
#endif /* 0 [failed searches] */
/* macrakis' bugs. */
buf.translate = upcase; /* message of 24 Jan 91 */
if (re_compile_pattern ("[!-`]", 5, &buf) != NULL)
printf ("Range test didn't compile.\n");
if (re_match (&buf, "A", 1, 0, NULL) != 1)
printf ("Range test #1 didn't match.\n");
if (re_match (&buf, "a", 1, 0, NULL) != 1)
printf ("Range test #2 didn't match.\n");
buf.translate = 0;
#define FAO_PATTERN "\\(f\\(.\\)o\\)+"
if (re_compile_pattern (FAO_PATTERN, strlen (FAO_PATTERN), &buf) != NULL)
printf ("faofdx test didn't compile.\n");
if (re_search (&buf, "faofdx", 6, 0, 6, &regs) != 0)
printf ("faofdx test didn't match.\n");
if (regs.start[1] != 0 || regs.end[1] != 3)
printf ("faofdx test, reg #1 wrong.\n");
if (regs.start[2] != 1 || regs.end[2] != 2)
printf ("faofdx test, reg #2 wrong.\n");
TEST_REGISTERS ("\\(a\\)*a", "aaa", 0, 3, 1, 2, -1, -1);
test_fastmap ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)", " \n", 1, 0);
/* 40 lines, 48 a's in each line. */
test_match ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:");
/* 640 a's followed by one b, twice. */
test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab");
/* 640 a's followed by two b's, twice. */
test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb");
/* Dave G. bug: Reference to a subexpression which didn't match.
Should fail. */
re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
test_match ("(ooooooooooone())-annnnnnnnnnnd-(twooooooooooo\\2)",
"ooooooooooone-annnnnnnnnnnd-twooooooooooo");
test_match ("(o|t)", "o");
test_match ("(o()|t)", "o");
test_match ("(o|t)", "o");
test_match ("(ooooooooooooooo|tttttttttttttttt())", "ooooooooooooooo");
test_match ("(o|t())", "o");
test_match ("(o()|t())", "o");
test_match ("(ooooooooooooooooooooooooone()|twooooooooooooooooooooooooo())", "ooooooooooooooooooooooooone");
test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-t");
test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-f");
test_should_match = 0;
test_match ("(foo(bar)|second)\\2", "second");
test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-t");
test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-f");
re_set_syntax (RE_SYNTAX_EMACS);
test_match ("\\(foo\\(bar\\)\\|second\\)\\2", "secondbar");
test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
"one-and-four");
test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
"two-and-three");
test_should_match = 1;
re_set_syntax (RE_SYNTAX_EMACS);
test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
"one-and-three");
test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
"two-and-four");
TEST_REGISTERS (":\\(.*\\)", ":/", 0, 2, 1, 2, -1, -1);
/* Bug with `upcase' translation table, from Nico Josuttis
<nico@bredex.de> */
test_should_match = 1;
test_case_fold ("[a-a]", "a");
printf ("\nFinished regression tests.\n");
}
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -0,0 +1,39 @@
/* Indexed by a character, gives the upper case equivalent of the
character. */
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
};

View File

@ -0,0 +1,21 @@
#include <stdio.h>
extern char *malloc ();
#ifndef NULL
#define NULL 0
#endif
void *
xmalloc (size)
unsigned size;
{
char *new_mem = malloc (size);
if (new_mem == NULL)
{
fprintf (stderr, "xmalloc: request for %u bytes failed.\n", size);
abort ();
}
return new_mem;
}