Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -36,6 +36,15 @@ # xargs -n1 | sort | uniq -d; # done +# 20201225: libregex removed +OLD_FILES+=usr/lib/libgnuregex.so +OLD_LIBS+=usr/lib/libgnuregex.so.5 +OLD_FILES+=usr/lib/libgnuregex_p.a + +# 20201225: gnugrep removed +OLD_FILES+=usr/bin/gnugrep +OLD_FILES+=usr/share/man/man1/gnugrep.1.gz + # 20201215: in-tree gdb removed OLD_FILES+=usr/libexec/gdb OLD_FILES+=usr/libexec/kgdb Index: gnu/lib/Makefile =================================================================== --- gnu/lib/Makefile +++ gnu/lib/Makefile @@ -6,10 +6,6 @@ SUBDIR.${MK_DIALOG}+= libdialog SUBDIR.${MK_TESTS}+= tests -.if ${MK_GNU_GREP} != "no" -SUBDIR+= libregex -.endif - SUBDIR_PARALLEL= .include Index: gnu/lib/libregex/Makefile =================================================================== --- gnu/lib/libregex/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# $FreeBSD$ - -LIB= gnuregex -SHLIB_MAJOR= 5 - -REGEXDIR= ${SRCTOP}/contrib/libgnuregex -.PATH: ${REGEXDIR} - -WARNS?= 1 - -SRCS= gnuregex.c -INCSGROUPS= INCS WRINCS PXINCS -INCS= regex.h.patched -INCSNAME= regex.h -INCSDIR= ${INCLUDEDIR}/gnu -WRINCS= gnuregex.h -PXINCS= ${REGEXDIR}/regex.h -PXINCSDIR= ${INCSDIR}/posix - -CFLAGS+= -D__attribute_warn_unused_result__="" -CFLAGS+= -DHAVE_CONFIG_H -I${.CURDIR} -I${REGEXDIR} - -CLEANFILES= regex.h.patched gnuregex.c -regex.h.patched: regex.h - sed 's===g' \ - < ${.ALLSRC} > ${.TARGET} - -gnuregex.c: regex.c - sed 's===g' \ - < ${.ALLSRC} > ${.TARGET} - -.include Index: gnu/lib/libregex/Makefile.depend =================================================================== --- gnu/lib/libregex/Makefile.depend +++ /dev/null @@ -1,16 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: gnu/lib/libregex/config.h =================================================================== --- gnu/lib/libregex/config.h +++ /dev/null @@ -1,15 +0,0 @@ -/* $FreeBSD$ */ - -#define _REGEX_RE_COMP 1 -#define HAVE_LANGINFO_H 1 -#define HAVE_LANGINFO_CODESET 1 -#define HAVE_LOCALE_H 1 -#define HAVE_WCHAR_H 1 -#define HAVE_WCTYPE_H 1 -#define HAVE_ISBLANK 1 -#define HAVE_WCRTOMB 1 -#define HAVE_MBRTOWC 1 -#define HAVE_WCSCOLL 1 -#define HAVE_ALLOCA 1 -#define HAVE_STDBOOL_H 1 -#define HAVE_STDINT_H 1 Index: gnu/lib/libregex/gnuregex.h =================================================================== --- gnu/lib/libregex/gnuregex.h +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * Copyright (c) 2004 David E. O'Brien - * Copyright (c) 2004 Andrey A. Chernov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifdef __GNUC__ -#warning "Use -I/usr/include/gnu and instead of " -#endif -#include Index: gnu/lib/libregex/regex.h =================================================================== --- gnu/lib/libregex/regex.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $FreeBSD$ */ -#ifndef _REGEX_H - -#ifndef __USE_GNU -#define __USE_GNU -#endif - -#include - -/* Document internal interfaces. */ -extern reg_syntax_t __re_set_syntax (reg_syntax_t __syntax); - -extern const char *__re_compile_pattern (const char *__pattern, size_t __length, - struct re_pattern_buffer *__buffer); - -extern int __re_compile_fastmap (struct re_pattern_buffer *__buffer); - -extern int __re_search (struct re_pattern_buffer *__buffer, const char *__string, - int __length, int __start, int __range, - struct re_registers *__regs); - -extern int __re_search_2 (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); - -extern int __re_match (struct re_pattern_buffer *__buffer, const char *__string, - int __length, int __start, struct re_registers *__regs); - -extern int __re_match_2 (struct re_pattern_buffer *__buffer, - const char *__string1, int __length1, - const char *__string2, int __length2, int __start, - struct re_registers *__regs, int __stop); - -extern void __re_set_registers (struct re_pattern_buffer *__buffer, - struct re_registers *__regs, - unsigned int __num_regs, - regoff_t *__starts, regoff_t *__ends); - -extern int __regcomp (regex_t *__restrict __preg, - const char *__restrict __pattern, - int __cflags); - -extern int __regexec (const regex_t *__restrict __preg, - const char *__restrict __string, size_t __nmatch, - regmatch_t __pmatch[__restrict_arr], - int __eflags); - -extern size_t __regerror (int __errcode, const regex_t *__restrict __preg, - char *__restrict __errbuf, size_t __errbuf_size); - -extern void __regfree (regex_t *__preg); - -#endif /* _REGEX_H */ Index: gnu/usr.bin/Makefile =================================================================== --- gnu/usr.bin/Makefile +++ gnu/usr.bin/Makefile @@ -4,7 +4,6 @@ SUBDIR.${MK_DIALOG}+= dialog SUBDIR.${MK_GNU_DIFF}+= diff3 -SUBDIR.${MK_GNU_GREP}+= grep SUBDIR.${MK_TESTS}+= tests SUBDIR_PARALLEL= Index: gnu/usr.bin/grep/AUTHORS =================================================================== --- gnu/usr.bin/grep/AUTHORS +++ /dev/null @@ -1,44 +0,0 @@ -Mike Haertel wrote the main program and the dfa and kwset matchers. - -Arthur David Olson contributed the heuristics for finding fixed substrings -at the end of dfa.c. - -Richard Stallman and Karl Berry wrote the regex backtracking matcher. - -Henry Spencer wrote the original test suite from which grep's was derived. - -Scott Anderson invented the Khadafy test. - -David MacKenzie wrote the automatic configuration software use to -produce the configure script. - -Authors of the replacements for standard library routines are identified -in the corresponding source files. - -The idea of using Boyer-Moore type algorithms to quickly filter out -non-matching text before calling the regexp matcher was originally due -to James Woods. He also contributed some code to early versions of -GNU grep. - -Mike Haertel would like to thank Andrew Hume for many fascinating discussions -of string searching issues over the years. Hume & Sunday's excellent -paper on fast string searching (AT&T Bell Laboratories CSTR #156) -describes some of the history of the subject, as well as providing -exhaustive performance analysis of various implementation alternatives. -The inner loop of GNU grep is similar to Hume & Sunday's recommended -"Tuned Boyer Moore" inner loop. - -More work was done on regex.[ch] by Ulrich Drepper and Arnold -Robbins. Regex is now part of GNU C library, see this package -for complete details and credits. - -Arnold Robbins contributed to improve dfa.[ch]. In fact -it came straight from gawk-3.0.3 with small editing and fixes. - -Many folks contributed see THANKS, if I omited someone please -send me email. - -Alain Magloire maintained GNU grep until version 2.5e. - -Bernhard "Bero" Rosenkr舅zer is the current maintainer. - Index: gnu/usr.bin/grep/COPYING =================================================================== --- gnu/usr.bin/grep/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - 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. - - - Copyright (C) 19yy - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - , 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. Index: gnu/usr.bin/grep/ChangeLog =================================================================== --- gnu/usr.bin/grep/ChangeLog +++ /dev/null @@ -1,2477 +0,0 @@ -2002-03-26 Bernhard Rosenkraenzer - * src/grep.c: Don't fail if we don't have an stdout fd and -q - is used (happens e.g. on calls from hotplug scripts) - * src/grep.c: Don't hang forever if fed with an empty string to - grep for and --color enabled - * src/grep.c: Fix infinite loop on - echo "1 one" | grep -E "[0-9]*" -o - echo "1 one" | grep -E "[0-9]*" --color - * po/*: Sync wiith translation project - * src/grep.c, src/Makefile.am, configure.in: Add patch from - Paul Eggert to comply with ridiculous - guidelines (don't act differently if invoked as egrep or fgrep) - * configure.in: Bump version number, require a recent autoconf - -2002-03-14 Bernhard Rosenkraenzer - * src/Makefile.am, po/Makefile.in.in: Support DESTDIR properly - * tests/bre.tests: Add fix from - Peter Breitenlohner - -2002-03-13 Bernhard Rosenkraenzer - * configure.in, m4/regex.m4, m4/malloc.m4, m4/realloc.m4: - Don't set LIBOBJS directly, autoconf 2.53 doesn't like it - * intl/*: Sync with gettext 0.11 - * po/*: Sync with translation project - * configure.in, src/Makefile.am: Don't duplicate code - make - egrep and fgrep links to grep and set matcher based on - application name, suggestion from - Guillaume Cottenceau - * src/grep.c: (prline) Add fix for -i --color from - Jim Meyering - * configure.in: Version 2.5; release - -2002-01-23 Bernhard Rosenkraenzer - * configure.in: Version 2.5g - * Makefile.cvs, grep.spec: Add packaging tools - Merge djgpp changes from Andrew Cottrell : - * src/grep.c: Added conditional compilation for DJGPP - * djgpp: remove directory as it is no longer required with DJGPP 2.03 - (or 2.04 when released) - * README.DOS: Moved djgpp/readme to readme.dos - * PATCHES.AC, PATCHES.AM: delete files - redundant - * configure.in, Makefile.am: remove djgpp directory from list - -2002-01-22 Bernhard Rosenkraenzer - * doc/grep.texi, doc/grep.1, NEWS: Document --label - * po/ru.po: Sync with translation project - * po/grep.pot: Sync with source - -2002-01-18 Bernhard Rosenkraenzer - * src/grep.c: Add --label, based on patch from Stepan Koltsov - -2001-11-20 Bernhard Rosenkraenzer - * autogen.sh: Don't hardcode aclocal dir - -2001-11-19 Bernhard Rosenkraenzer - * src/grep.c: Add --only-matching (-o) switch (see NEWS) - * doc/grep.texi, doc/grep.1, NEWS: Document changes - * configure.in, lib/Makefile.am: Don't use internal getopt if - we're on a system that provides a working getopt function - -2001-09-25 Bernhard Rosenkraenzer - * configure.in: Detect pcre correctly even when it's in - non-standard locations, using pcre-config - * src/grep.c: Add --color={always,never,tty} argument (like in ls) - * src/grep.c: Turn off blinking in the default colorization - * src/grep.c: Add --devices (-D) switch (analogous to --directories) - * src/dfa.c: Fix an i18n bug: echo "A" | grep '[A-Z0-9]' wouldn't work - in non-C-Locales on systems using current versions of glibc. - * AUTHORS: Change maintainer, credit Alain for his work until now - * configure.in, m4/decl.m4, m4/dosfile.m4, m4/gettext.m4, - m4/init.m4, m4/install.m4, m4/largefile.m4, m4/lcmessage.m4, - m4/header.m4, m4/isc-posix.m4, m4/missing.m4, m4/progtest.m4, - m4/sanity.m4: - Fix build with autoconf 2.5x, retain 2.1x compatibility for now - * autogen.sh: Add some crude hacks to make it possible to build with - both autoconf 2.5x and 2.1x - * acconfig.h: removed (no longer required) - * Makefile.am: add cvs-clean target - * doc/grep.texi, doc/grep.1, NEWS: Document changes - (--color, --devices, -D) - * src/dfa.c, src/grep.c: Add vim modelines - -2001-08-30 Alain Magloire - - * configure.in: Add gl in ALL_LINGUAS. - -2001-08-30 Kurt D Schwehr - - * doc/grep.1: Warn that grep insert a "--" between groups of matches, - when using the context options. - * doc/grep.texi: Likewised. - -2001-08-25 Heikki Korpela - - * doc/grep.texi: Point out that some Platforms do not support - reading of directories and silently ignore them. - -2001-08-21 Alain Magloire - - * lib/malloc.c: New file: - * lib/realloc.c: New file: - * lib/Makefile.am: Add malloc.c and realloc.c in EXTRA_DIST. - -2001-07-31 Alain Magloire - - * po/*.po: New files from the translation team: - grep-2.5e.de.po grep-2.5e.el.po grep-2.5e.eo.po grep-2.5e.es.po - grep-2.5e.et.po grep-2.5e.fr.po grep-2.5e.gl.po grep-2.5e.it.po - grep-2.5e.pl.po grep-2.5e.sl.po - -2001-07-31 Andreas Schwab - - * src/grep.c: Fix all uses of error to pass a proper format - string. - -2001-07-29 Alain Magloire - - * grep/src/grep.c (usage): Typos corrected. - Patches from Santiago Vila. - -2001-07-29 Alain Magloire - - David Clissold, wrote: - a small bug in the GNU grep 2.4.2, which may have gone unnoticed - because it only causes a failure if building on a system with large - files enabled (e.g. an "off_t" is a "long long" rather than a "long"). - savedir() takes on off_t argument, but in grepdir() the parameter - is cast to an (unsigned). Well, if an off_t is larger than an int, - the value gets truncated. This would not normally have an effect on a - little-endian platform (unless the file is >2GB), but on a big-endian - system it will always fail. The external effect is that - "grep -r foo dir_name" fails with ENOMEM (from malloc() within - savedir()). - - * grep/src/grep.c (grepdir): Remove the (unsigned) cast when calling - savedir(). - Patch from David Clissold. - -2001-07-29 Alain Magloire - - * grep/doc/grep.texi: In Bugs report use {n,m} for consistency. - * grep/doc/grep.1: Likewised. - Noted by Steven Lucy. - -2001-04-27 Isamu Hasegawa - - * dfa.c (mblen_buf) : New variable contains the amount of remain - byte of corresponding multibyte character in the input string. - (SKIP_REMAIN_MB_IF_INITIAL_STATE) : Use mblen_buf. - (match_anychar) : Use mblen_buf. - (match_mb_charset) : Use mblen_buf. - (transit_state_consume_1char) : Use mblen_buf. - (transit_state) : Use inputwcs to get current (multibyte) character. - (dfaexec) : Add initialization of mblen_buf. - -2001-04-27 Isamu Hasegawa - - * dfa.c (addtok) : Set appropriate value to multibyte_prop. - (dfastate) : Add the initialization of the variable. - (dfaexec) : Call transit_state if d->fail may transit by - multibyte characters. - (transit_state_singlebyte) : Clean up unnecessary code. - (transit_state_consume_1char) : Likewise. - (transit_state) : Add checking for word and newline. - -2001-04-19 Isamu Hasegawa - - * search.c (check_multibyte_string) : Check the case when mbclen == 0. - -2001-04-11 Isamu Hasegawa - - * search.c (check_multibyte_string) : Check the head of multibyte - characters, and optimize a bit. - (EGexecute) : Optimize a bit. - (Fexecute) : Fix the index. - -2001-04-02 Alain Magloire - - * lib/regex.c: Update from GNU lib C, with the changes - provided by Paul Eggert. - * lib/posix/regex.h: Likewise. - -2001-02-17 Paul Eggert - - Stop trying to support hosts that have nonstandard declarations for - mbrtowc and/or mbstate_t. It's not worth the portability hassle. - - * lib/quotearg.c (mbrtowc, mbsinit): Remove workaround macros - for hosts that have mbrtowc but not mbstate_t, as we now - insist on proper declarations for both before using mbrtowc. - -2001-03-18 Alain Magloire - - * configure.in: Call AC_MBSTATE_T. - * Makefile.am: Add mbstate_t.m4 - * m4/Makefile.am: Add mbstate_t.m4 - * m4/mbstate_t.m4: New m4 macro. - * lib/strtol.c: Define CHAR_BITS. - Uwe H. Steinfeld, Ruslan Ermilov, Volkert Bochert, noted - that mbstate_t was not define for certain platforms. - -2001-03-18 Paul Eggert - - * src/grep.c (fillbuf): Fix storage allocation performance - bug: buffer was doubling in size in many cases where it didn't - have to. - -2001-03-17 Paul Eggert - - * src/grep.c (fillbuf): Avoid unnecessary division by 2. - Don't check xrealloc return value; it's guaranteed to be nonzero. - (fillbuf, grepdir): Use xalloc_die rather than error; it's shorter. - -2001-03-17 Alain Magloire - - * src/grep.c (context_length_arg): error () passing wrong format. - Spotted by Jim Meyering. - -2001-03-07 Alain Magloire - - * README-alpha: Removed reference to GNU tar, add the location - of the CVSROOT. - -2001-03-06 Alain Magloire - - Only the Regex patterns should be split in an array, patterns[]. - The dfa and KWset compiled patterns should remain global and the - patterns compiled all at once. - - * src/search.c: include "error.h" and "xalloc.h" to get prototyping - of x*alloc() and error(). - (kwsinit): Reverse to previous behaviour and takes no argument. - (kwsmusts): Likewised. - (Gcompile): For the regex pattern, split them and each pattern - is put in different compiled structure patterns[]. The patterns - are given to dfacomp() and kwsmusts() as is. - (Ecompile): Likewised. - (Fcompile): Reverse to the old behaviour of compiling the enire - patterns in one shot. - (EGexecute): If falling to GNU regex for the matching, loop in the - array of compile patterns[] to find a match. - (error): Many error () were call with arguments in the wrong order. - * tests/file.sh: Simple test to check for pattern in files. - - Reaction to bug report fired by Greg Louis - -2001-03-06 Isamu Hasegawa - - In multibyte environments, handle multibyte characters as single - characters in bracket expressions. - - * src/dfa.h (mb_char_classes) : new structure. - (mbcsets): new variable. - (nmbcsets): new variable. - (mbcsets_alloc) : new variable. - * src/dfa.c (prtok) : handle MBCSET. - (fetch_wc): new function to fetch a wide character. - (parse_bracket_exp_mb) : new function to handle multibyte character - in lex(). - (lex): invoke parse_bracket_exp_mb() for multibyte bracket expression. - (atom): handle MBCSET. - (epsclosure): likewise. - (dfaanalyze): likewise. - (dfastate): likewise. - (match_mb_charset): new function to judge whether a bracket match - with a multibyte character. - (check_matching_with_multibyte_ops) : handle MBCSET. - (dfainit): initialize new variables. - (dfafree): free new variables. - -2001-03-04 Alain Magloire - - To get more in sync with other GNU utilities like GNU tar and fetish - all the supporting functions are now under lib. - Thanks to Jim Meyering, Volkert Bochert and Paul Eggert for - the code and the reminders. - - * src/grep.c (fatal): Function removed, using error () from - lib/error.c instead. - (usage): Copyright updated. - (error): Function removed, using error () from lib/error.c instead, - adjust prototypes. - (prog): Global variable rename to program_name, to work with new - lib/error.c. - (xrealloc): Removed using lib/xmalloc.c. - (xmalloc): Removed using lib/xmalloc.c - (main): Register with atexit() to check for error on stdout. - * configure.in: Check for atexit(), call jm_MALLOC, jm_RELLOC and - jm_PREREQ_ERROR. - * tests/bre.awk: Removed the hack to drain the buffer since we - always fclose(stdout) atexit. - * tests/ere.awk: Likewise. - * tests/spencer1.awk: Likewise. - * bootstrap/Makefile.try: Update the Makefile to reflect the changes - in the new hierarchy. - - * README-alpha: New File. - * m4/realloc.m4: New File. - * m4/malloc.m4: New File. - * m4/error.m4: New File. - * m4/Makefile.am: Updated. - * lib: New directory. - * lib/Makefile.am: New file. - * lib/closeout.c: New file. - * lib/closeout.h: New file. - * lib/fnmatch.c: New file. - * lib/fnmatch.h: New file. - * lib/atexit.c: New file. - * lib/error.c: New file. - * lib/error.h: New file. - * lib/quotearg.h: New file. - * lib/quotearg.c: New file. - * lib/xmalloc.c: New file. - * lib/posix: New directory. - * lib/posix/Makefile.am: New file. - * src/getopt.c: Moved to lib. - * src/getopt1.c: Moved to lib. - * src/getopt.h: Moved to lib. - * src/alloca.c: Moved to lib. - * src/exclude.c: Moved to lib. - * src/exclude.h: Moved to lib. - * src/hard-locale.h: Moved to lib. - * src/hard-locale.c: Moved to lib. - * src/isdir.c: Moved to lib. - * src/mechr.c: Moved to lib. - * src/obstack.c: Moved to lib. - * src/obstack.h: Moved to lib. - * src/regex.c: Moved to lib. - * src/regex.h: Moved to lib. - * src/posix: Moved to lib. - * src/posix/regex.h: Moved to lib. - * src/savedir.h: Moved to lib. - * src/savedir.c: Moved to lib. - * src/stpcpy.c: Moved to lib. - * src/strtoul.c: Moved to lib. - * src/strtol.c: Moved to lib. - * src/strtoull.c: Moved to lib. - * src/strtoumax.c: Moved to lib. - * src/xstrtol.c: Moved to lib. - * src/xstrtol.h: Moved to lib. - * src/xstrtoumax.c: Moved to lib. - -2001-03-01 Isamu Hasegawa - - Implement the mechanism to match with multibyte characters, - and use it for `period' in multibyte environments. - - * dfa.h (mbps): new variable. - * dfa.c (prtok): handle ANYCHAR. - (lex): use ANYCHAR for `period' in multibyte environments. - (atom): handle ANYCHAR. - (state_index): initialize mbps in multibyte environments. - (epsclosure): handle ANYCHAR. - (dfaanalyze): handle ANYCHAR. - (dfastate): handle ANYCHAR. - (realloc_trans_if_necessary): new function. - (transit_state_singlebyte): new function. - (match_anychar): new function. - (check_matching_with_multibyte_ops): new function. - (transit_state_consume_1char): new function. - (transit_state): new function. - (dfaexec): invoke transit_state if expression can match with - a multibyte character in multibyte environments. - (dfamust): handle ANYCHAR. - -2001-03-01 Alain Magloire - - * src/exclude.c: New file. - * src/exclude.h: New file. - * src/grep.c (main): Took the GNU tar code to handle - the option --include, --exclude, --exclude-from. - Files are check for a match, with exlude_filename (). - New option --exclude-from. - * src/savedir.c: Call exclude_filename() to check for - file pattern exclusion or inclusion. - * configure.in: --disable-pcre rename to --disable-perl-regexp. - - -2001-02-25 Alain Magloire - - * src/dfa.c: Typo corrected. - Noted by Isamu Hasegawa. - * src/savedir.c: Typos corrected. - -2001-02-22 Alain Magloire - - * src/savedir.c (isdir1): New function, calling isdir with - the correct pathname. - -2001-02-19 Isamu Hasegawa - - Avoid incorrect state transition in multibyte environments. - - * dfa.h (nmultibyte_prop): new variable. - (multibyte_prop): new variable. - * dfa.c (addtok): set inputwcs. - (dfastate): avoid incorrect state transition in multibyte - environments. - (dfaexec): likewise. - (dfainit): init multibyte_prop. - (dfafree): free multibyte_prop. - (inputwcs): new variable. - -2001-02-19 Isamu Hasegawa - - Handle a multibyte character followed by '*', '+', and '{n,m}' - correctly. - - * dfa.c (update_mb_len_index): new function. - Support for multibyte string. - (FETCH): call update_mb_len_index. - (lex): check cur_mb_index not to misunderstand multibyte characters. - (atom): make a tree from a multibyte character. - (dfaparse): initialize new variables. - (mbs): new variable. - (cur_mb_len): new variable. - (cur_mb_index): new variable. - -2001-02-18 Jim Meyering - - * m4/dosfile.m4 (AC_DOSFILE): Move AC_DEFINEs out of AC_CACHE_CHECK. - -2001-02-17 Alain Malgoire - - * doc/grep.texi: Document the new options and the new behaviour - back-references are local. Use excerpt from Karl Berry regex - texinfo. - - * bootstrap/Makefile.try: Added xstrtoumax.o xstrtoul.o hard-local.o - -2001-02-17 Alain Magloire - - From Guglielmo 'bond' Bondioni : - The bug was that using a multi line file that contained REs (one per - line), backreferences in the REs were considered global (to the file) - and not local (to the line). - That is, \1 in line n refers to the first \(.\) in the whole file, - rather than in the line itself. - - From Tapani Tarvainen : - # Re: grep -e '\(a\)\1' -e '\(b\)\1' - That's not the way it should work: multiple -e arguments - should be treated as independent patterns and back references - should not refer to previous ones. - - From Paul Eggert : - GNU grep currently does not issue - diagnostics for the following two cases, both of which are erroneous: - grep -e '[' -e ']' - grep '[ - ]' - POSIX requires a diagnostic in both cases because '[' is not a valid - regular expression. - - To overcome those problems, grep no longer pass the concatenate - patterns to GNU regex but rather compile each patterns separately - and keep the result in an array. - - * src/search.c (patterns): New global variable; a structure array - holding the compiled patterns. - Declare function prototypes to minimize error. - (dfa, kswset, regexbuf, regs): Removed, no longer static globals, but - rather fields in patterns[] structure per motif. - (Fcompile): Alloc an entry in patterns[] to hold the regex. - (Ecompile): Alloc an entry per motif in the patterns[] array. - (Gcompile): Likewise. - (EGexecute): Loop through of array of patterns[] for a match. - -2001-02-17 Alain Magloire - - From Bernd Strieder : - # tail -f logfile | grep important | do_something_urgent - # tail -f logfile | grep important | do_something_taking_very_long - If grep does full buffering in these cases then the urgent operation - does not happen as it should in the first case, and in the second case - time is lost due to waiting for the buffer to be filled. - This is clearly spoken not grep's fault in the first place, but libc's. - There is a heuristic in libc that make a stream line-buffered only if a - terminal is on the other end. This doesn't take care of the cases where - this connection is somehow indirect. - - * src/grep.c (line_buffered): new option variable. - (prline): if line_buffered is set fflush() is call. - (usage): line_buffered new option. - Input from Paul Eggert, doing setvbuf() may not be portable - and breaks grep -z. - -2001-02-16 Alain Magloire - - Patch from Isamu Hasegawa, for multibyte support. - This patch prevent kwset_matcher from following problems. - For example, in SJIS encoding, one character has the codepoint 0x895c. - So the second byte of the character can match with '\' incorrectly. - And in eucJP encoding, there are the characters whose codepoints are - 0xa5b9, 0xa5c8. On the other hand, there is one character whose - codepoint is 0xb9a5. So 0xb9a5 can match with 2nd byte of 0xa5b9 - and 1st byte of 0xa5c8. - - * configure.in: Add check for mbrtowc. - * src/search.c (check_multibyte_string): new function. - Support for multibyte string. - (EGexecute): call check_multibyte_string when kwset is set. - (Fexecute): call to check_multibyte_string. - (MBS_SUPPORT): new macro. - (MB_CUR_MAX): new macro. - -2001-02-16 Alain Magloire - - * djgpp/config.bat: Fix for 4dos.com. - * m4/dosfile.m4 (HAVE_DOS_FILE_CONTENTS): Was not set. - Bugs noted and patched by Juan Manuel Guerrero. - -2001-02-16 Alain Magloire - - A much requested feature, the possibility to select - files when doing recurse : - # find . -name "*.c" | xargs grep main {} - # grep --include=*.c main . - # find . -not -name "*.c" | xargs grep main {} - # grep --exclude=*.c main . - - * src/grep.c (short_options): -R equivalent to -r. - (#ifdef) : Fix some inconsistencies in the use of #ifdefs, prefer - #if defined() wen possible. - (long_options): Add --color, --include and exclude. - (Usage): Description of new options. - (color): Rename color variable to color_option. - Removed 'always|never|auto' arguments, not necessary for grep. - (exclude_pattern): new variable, holder for the file pattern. - (include_pattern): new variable, hoder for the file pattern. - * src/savedir.c: Signature change, take two new argmuments. - * doc/grep.texi: Document, new options. - * doc/grep.man: Document, new options. - -2001-02-09 Alain Magloire - - * src/grep.c (long_options): Added equivalent to -r with -R. - * src/grep.c (usage): added --color and --colour. - Noted with patch from, H.Merijn Brand and Wichert Akkerman. - -2001-02-09 Alain Magloire - - Patch from Ulrich Drepper to provide hilighting. - - * src/grep.c: New option --color. - (color): New static var. - (COLOR_OPTION): new constant. - (grep_color): new static var. - (prline): Now when color is set prline() will call the current matcher - to find the offset of the matching string. - * src/savedir.c: Take advantage of _DIRENT_HAVE_TYPE if supported. - * src/search.c (EGexecute, Fexecute, Pexecute): Take a new argument - when doing exact match for the color hiligting. - -2000-09-01 Brian Youmans - - * doc/grep.texi: Typo fixes. - -2000-08-30 Paul Eggert - - * doc/grep.texi (Usage): Talk about what "grep -r hello *.c" - means. - -2000-08-20 Paul Eggert - - Handle range expressions correctly even when they match - strings with two or more characters. - - * src/dfa.h (CRANGE): New enum value. Comment fix. - - * src/dfa.c: Include if HAVE_SETLOCALE. - Include "hard-locale.h". - (prtok): Print CRANGE. - (hard_LC_COLLATE): New static var. - (lex): Return CRANGE when parsing a character range in a hard locale. - Don't use strcoll; it's no longer needed and wasn't correct anyway. - Use unsigned rather than token to hold unsigned chars. - (addtok): Comment fix. - (atom): Treat a CRANGE as if it were (.\1), approximately. - (dfaparse): Initialize hard_LC_COLLATE. - - * src/Makefile.am (base_sources): Add hard-locale.c, hard-locale.h. - - * src/hard-locale.c, src/hard-locale.h: New files, taken from - textutils. - -2000-08-20 Paul Eggert - - * tests/Makefile.am (TESTS_ENVIRONMENT): Add LC_ALL=C, since - some of the tests assume the C locale. - -2000-08-16 Paul Eggert - - * src/search.c (Gcompile, Ecompile): -x overrides -w, for - consistency with fgrep. Don't assume that sizes fit in 'int'. - Fix comments to match code. - -2000-06-06 Paul Eggert - - * src/grep.c (grepdir): Don't look at st_dev when testing for - Mingw32 bug. - -2000-06-05 Paul Eggert - - Port to Mingw32, based on suggestions from Christian Groessler - . - - * src/isdir.c: New file, taken from fileutils. - - * src/Makefile.am (base_sources): Add isdir.c. - - * src/grep.c (grepfile): Use isdir instead of doing it inline. - (grepdir): Suppress ancestor check if the directory's inode and device - are both zero, as that occurs only on Mingw32 which doesn't support - inode or device. - - * src/system.h (isdir): New decl. - (is_EISDIR): Depend on HAVE_DIR_EACCES_BUG, not D_OK. - Use isdir, not access. - -2000-06-02 Paul Eggert - - Problen noted by Gerald Stoller - - * src/grep.c (main): POSIX.2 says that -q overrides -l, which - in turn overrides the other output options. Fix grep to - behave that way. - -2000-05-27 Paul Eggert - - Simplify and tune the buffer allocation strategy. Do not reserve a - large save area: reserve only enough bytes to hold the residue, plus - page alignment. Put a newline sentinel before the buffer, for speed - when searching backwards for newline. - - * src/grep.c (ubuffer, bufsalloc, PREFERRED_SAVE_FACTOR, page_alloc): - Remove. All uses changed. - (INITIAL_BUFSIZE): New macro. - (reset, fillbuf): Use simpler buffer allocation strategy. - (reset): Check for preposterously large pagesize that would cause - later calculations to overflow. - (fillbuf): Do not resize buffer if there's room at the end for - at least one more page. This greatly increases performance when - reading from non-regular files that contain no newlines. - When growing the buffer, double its size instead of using a - more complicated algorithm. - (prtext, grep): Speed up by relying on the newline sentinel before the - start of the buffer. - (grep): When looking backwards for the last newline in a buffer, - stop when we hit the residue, since it can't contain a newline. - This avoids an O(N**2) algorithm when reading binary data from - a pipe. Use a sentinel to speed up the backward search for newline. - (nlscan): Undo previous change; it wasn't needed and just complicates - and slows down the code a tad. - -2000-05-24 Paul Eggert - - Handle very large input counts better. Bug noted by Jim Meyering. - - * src/grep.c (totalcc, totalnl): Use uintmax_t, not off_t. - (add_count): New function. - (nlscan, prline, grep): Use it to check line and byte count overflows. - (nlscan, grep): Don't keep track of counts when not asked to; this - avoids unnecessary overflow diagnostics. - (print_offset_sep): Now takes args of type uintmax_t and char, - not off_t and int. - -2000-05-16 Paul Eggert - - Problem reported by Bob Proulx , this patch - is base on his finding, with appropiate corrections. - - * src/grep.c (main): Fix bug: -x and -w matched even when no - patterns were specified. - * tests/empty.sh: Test for -x and -w bug in grep 2.4.2. - -2000-04-24 Paul Eggert - - POSIX.2 conformance fixes: grep -q now exits with status zero - if an input line is selected, even if an error also occurs. - grep -s no longer affects exit status. - - * src/grep.c (suppress_errors): Move definition earlier so - that suppressible_error can use it. - (suppressible_error): New function. - (exit_on_match): New var. - (grepbuf): If exit_on_match is nonzero, exit with status zero - immediately. - (grep, grepfile, grepdir): Invoke suppressible_error. - (main): -q sets exit_on_match. - - * doc/grep.1, doc/grep.texi, NEWS: - Document -q's behavior as required by POSIX.2. - - * tests/status.sh: - Test for -q and -s behavior as conforming to POSIX.2. - -2000-04-20 Paul Eggert - - * tests/Makefile.am (TESTS_ENVIRONMENT): - Set GREP_OPTIONS to the empty string. - -2000-04-20 Paul Eggert - - * tests/status.sh: Fix typo: test -b -> test -r. - -2000-04-20 Paul Eggert - - * src/dfa.c (lex): - Do not assume that [c] is equivalent to [c-c]; this isn't true - if LC_COLLATE specifies that some characters are equivalent. - (setbit_case_fold): New function. - (lex): Use it to simplify the code a bit. - -2000-04-17 Paul Eggert - - Do CRLF munging only if HAVE_DOS_FILE_CONTENTS, instead of - having it depend on O_BINARY (which leads to incorrect results - on BeOS, VMS, and MacOS). - - * bootstrap/Makefile.try (DEFS): Add -DHAVE_DOS_FILE_CONTENTS. - * src/system.h (SET_BINARY): Define only if HAVE_DOS_FILE_CONTENTS. - (O_BINARY): Do not define. - - * m4/dosfile.m4: Define HAVE_DOS_FILE_CONTENTS if it appears we're - using DOS. - - * src/grep.c (undossify_input, fillbuf, dosbuf.c, prline, main): - Depend on HAVE_DOS_FILE_CONTENTS, not O_BINARY, when handling CRLF - matters. - (grepfile, main): Depend on SET_BINARY, not O_BINARY, when - handling binary files on hosts that care about text versus binary. - -2000-04-17 Paul Eggert - - * lib/getpagesize.h (getpagesize): Define to B_PAGE_SIZE if - __BEOS__ is defined. Based on a fix by Bruno Haible - . - -2000-04-17 Bruno Haible - - * src/system.h [BeOS]: Ignore O_BINARY. - * src/getpagesize.h [BeOS]: Define getpagesize() as B_PAGE_SIZE. - -2000-04-10 Paul Eggert - - * doc/grep.1, doc/grep.texi, NEWS: -C now requires an operand. - * src/grep.c (short_options, long_options, main, usage): Likewise. - (context_length_arg): Renamed from ck_atoi. Now reports an error - and exits if the number is out of range for a context length. - (get_nondigit_option): New function, which checks for overflow - correctly, and which does not parse nonadjacent strings of digits - into a single number. - (main): Use get_nondigit_option instead of doing the code inline. - With -A, -B, and -C, optarg is now guaranteed to be nonzero. - -2000-04-08 Paul Eggert - - Now that we know that the input is always terminated by a - newline before the matching algorithms see it, clean up the - matching algorithms so that they no longer need to modify the - input by inserting a sentinel newline, and no longer worry - about running off the end of the buffer due to a missing sentinel. - - * src/grep.c (nlscan, prpending, prtext, grepbuf): Do not - worry about running off the end of the input buffer, since - it's now guaranteed to end in the sentinel newline. - * src/search.c (EGexecute, Pexecute): Likewise. - - * src/dfa.c (prtok, dfasyntax, dfaparse, copy, merge, state_index, - epsclosure, dfaexec, dfacomp): - Change many instances of "T *" to "T const *", to catch - any inadvertent programming errors made during this conversion. - * src/dfa.h (dfacomp, dfaexec, dfaparse): Likewise. - * src/grep.c (struct stats.parent, long_options, grepdir, - compile, execute, fillbuf, lastnl, lastout, nlscan, prline, - prpending, prtext, grepbuf, grep, grepfile, grepdir): Likewise. - * src/grep.h (struct matcher.compile, struct matcher.execute): - Likewise. - * src/kwset.c (struct kwset.trans, kwsalloc, kwsincr, treefails, - treedelta, hasevery, treenext, bmexec, cwexec, kwsexec): Likewise. - * src/kwset.h (kwsalloc, kwsincr, kwsexec): Likewise. - * src/search.c (kwsmusts, Gcompile, Ecompile, EGexecute, Pcompile, - Pexecute): Likewise. - - * src/dfa.c (dfaexec): - Use size_t, not char *, to avoid worrisome casts to convert - char const * to char *. - * src/dfa.h (dfaexec): Likewise. - * src/grep.c (execute): Likewise. - * src/grep.h (execute): Likewise. - * src/kwset.c (bmexec, cwexec, kwsexec): Likewise. - * src/kwset.h (struct kwsmatch.offset, kwsalloc, kwsincr, - kwsexec): Likewise. - * src/search.c (EGexecute, Fexecute, Pexecute): Likewise. - - * src/dfa.h (_PTR_T): Depend on defined __STDC__, not __STDC__. - (PARAMS): Depend on PROTOTYPES, not __STDC__. - - * src/dfa.c (dfasyntax): Last arg is unsigned char, not int. - * src/dfa.h (dfasyntax): Likewise. - - * src/dfa.h (struct dfa): Remove member newlines; no longer needed. - * src/dfa.c (build_state, dfaexec, dfafree): Do not worry - about special newline state. - - * src/search.c (matchers): Move definition to end of file, so - that we don't need forward decls. - (lastexact): Remove. - (kwset_exact_matches): New var; subsumes old lastexact var. - All uses changed. - - * src/dfa.c (index): Remove macro. - (REALLOC_IF_NECESSARY): Skip unnecessary test. - (tstbit, setbit, clrbit): Declare arg to be unsigned, to help compiler. - (copyset, zeroset, equal): Use C builtin primitives, to help compiler. - (dfaexec): Do not modify input string. - Remove newline parameter; no longer needed. - (comsubs): Use strchr, not index. - - * src/grep.h (matchers): Use fixed name size, not pointer (as - there's no need for the extra flexibility). All uses changed. - - * src/kwset.h (struct kwsmatch.offset): Renamed from beg, with - change of type to size_t. All uses changed. - - * src/grep.c (reset): No longer need kludge for dfaexec. Simplify. - (reset, grepbuf): Adjust to new interface for 'execute'. - (install_matcher): List is now terminated by null compile, - not null name. - Do not invoke setrlimit if that wouldn't change the limit. - - * src/dfa.c (xcalloc, xmalloc, xrealloc, prtok, tstbit, setbit, - clrbit, copyset, zeroset, notset, equal, charclass_index, - looking_at, lex, addtok, atom, nsubtoks, copytoks, closure, - branch, regexp, copy, insert, merge, delete, state_index, - build_state, build_state_zero, icatalloc, icpyalloc, istrstr, - ifree, freelist, enlist, comsubs, addlists, inboth): - Remove forward decls; no longer needed. - * src/grep.c (ck_atoi, usage, error, setmatcher, - install_matcher, prepend_args, prepend_default_options, - page_alloc, reset, fillbuf, grepbuf, prtext, prpending, prline, - print_offset_sep, nlscan, grep, grepfile): Likewise. - * src/kwset.c (enqueue, treefails, treedelta, hasevery, - treenext, bmexec, cwexec): Likewise. - * src/search.c (Gcompile, Ecompile, EGexecute, Fcompile, Fexecute, - Pcompile, Pexecute, kwsinit): Likewise. - - * src/search.c (Pcompile): Do not assume newly allocated - storage is zeroed. - -2000-04-06 Paul Eggert - - * doc/grep.1, doc/grep.texi, NEWS: Improve the explanation of - locale-dependent behavior of range expressions. Mention - LC_COLLATE, since this affects range expressions. - -2000-03-26 Paul Eggert - - * Makefile.am (ACINCLUDE_INPUTS): Add decl.m4, inttypes_h.m4, - uintmax_t.m4, ulonglong.m4, xstrtoumax.m4. - * m4/Makefile.am (EXTRA_DIST): Likewise. - - * src/Makefile.am (base_sources): - Add xstrtol.c, xstrtol.h, xstrtoumax.c. - (EXTRA_DIST): Add strtol.c. - - * configure.in (jm_AC_TYPE_UINTMAX_T, jm_AC_PREREQ_XSTRTOUMAX, - HAVE_DECL_STRTOUL, HAVE_DECL_STRTOULL): Add. - (AC_REPLACE_FUNCS): Add strtoul. - - * src/grep.c: Include xstrtol.h. - (ck_atio): Use xstrtoumax and do proper overflow checking. - (max_count, outleft): Now off_t, not int. - (main): Likewise. Use xstrtoumax to convert max_count from string. - - * acconfig.h (HAVE_DECL_STRTOUL, HAVE_DECL_STRTOULL): New #undefs. - (HAVE_STPCPY, ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, - HAVE_LC_MESSAGES): Remove. - - * m4/decl.m4, m4/inttypes_h.m4, m4/uintmax_t.m4, m4/ulonglong.m4, - m4/xstrtoumax.m4, src/strtol.c, src/strtoul.c, src/strtoull.c, - src/strtoumax.c, src/xstrtol.c, src/xstrtol.h, src/xstrtoumax.c: - New files, taken unchanged from textutils, fileutils, sh-utils - and/or tar. - -2000-03-23 Paul Eggert - - * src/search.c (Pcompile): Add support for NUL bytes in - Perl regular expressions. - -2000-03-23 Paul Eggert - - * NEWS, doc/grep.1, doc/grep.texi: Change --pcre to --perl-regexp. - * src/grep.c (long_options, usage): Likewise. - - * doc/grep.1, doc/grep.texi: Remove pgrep program. - * src/Makefile.am (bin_PROGRAMS): Likewise. - (pgrep_SOURCES): Remove. - - * src/grep.c (main): Rename matcher from "pgrep" to "perl". - * src/search.c (matchers): Likewise. - - * src/search.c: Do not include stdio.h; no longer needed. - (NILP): Remove. - (sub): No longer static. - (n_pcre): Remove. - (cre): No longer an array. Present only if HAVE_LIBPCRE. - (extra): New variable. - (Pcompile): Use fatal to report errors. - This also removes a possible core dump. - Add checks (marked FIXME) for restrictions in pcre. - Use pcre_maketables for proper localized behavior. - (Pcompile, Pexecute): Use GNU coding style. - The argument is a single pattern, not a list of patterns separated - by newlines; this is for consistency with grep and egrep. - Use pcre_study for speed. - (Pexecute): Abort if we lack pcre. - Abort if pcre_exec reports an impossible error. - Use code similar to the rest of search.c - to narrow down to the line we've found. - -2000-03-21 Alain Magloire - - * configure.in: added AC_CHECK_LIB(pcre, pcre_exec) - * ChangeLog: Typos corrected. - * src/search.c: new MACRO HAVE_LIBPCRE - -2000-03-21 H.Merijn Brand - - * src/Makefile.am(bin_PROGRAMS): added pgrep and new macro - pgrep_SOURCES. - * src/search.c: new functions Pcompile() and Pexecute() - to support PCRE. Update matcher[] array for pgrep. - * src/grep.c: new short and long option --pcre and -P. - usage() updated. - -2000-03-21 Bastiaan Stougie - - Improvement of the -m or --max-count option. Now works for NUM > 1 and - prints trailing context for the last matching line. - - * src/grep.c - (after_last_match): Is a new off_t variable that replaces inputhwm - to retain the correct input offset even after a call to fillbuf. Note - that after_last_match has a different meaning than inputhwm: - it always points to the offset in the input of the first byte after - the last matching line, and is 0 if no matching line has been found - yet. - (grep): Print trailing context after the NUMth match when the -m NUM - option is used. - (grep): Added comment. Should have been commented already. - (grepbuf): Now updates outleft correctly. This fixes the bug that the - -m NUM option did not stop after NUM lines for NUM greater than 1. - (grepbuf, prtext): Now update after_last_match instead of inputhwm. - (fillbuf): No longer updates inputhwm. - (prpending): When outputting trailing context of the max_count-th - matching line, stop at the first matching line. - (grepfile): Seek to after_last_match or eof, depending on the values - of outleft and bufmapped. - (usage): added the -m or --max-count option to the help message. - * doc/grep.texi, doc/grep.1: Document the change of the -m option. - -2000-03-17 Paul Eggert - - Add new -m or --max-count option, based on a suggestion by - Bastiaan Stougie. - - * doc/grep.texi, doc/grep.1: Document it. - * src/grep.c (short_options, long_options, main): Add it. - (inputhwm): New variable. - (fillbuf, prtext, grepbuf): Set it. - (bufmapped): Now a macro (defined to zero) if HAVE_MMAP is not defined. - (max_count, outleft): New variables. - (prtext, grepbuf, grep): Don't output more than outleft lines. - (grepfile): If grepping standard input, seek to the limit of what - we've read before exiting. This fixes a bug with mmapped input, - and is needed for proper -m support. - (main): Exit immediately if -m 0 is specified. - -2000-03-08 Alain Magloire - - * configure.in: version 2.4.2 - -2000-03-07 Paul Eggert - - * Make intl subdirectory match fileutils, tar, etc.; - see intl/ChangeLog for details. - - * src/getpagesize.h: Reformat to match latest fileutils. - - * src/savedir.c (savedir): Work even if directory size is - negative; this can happen with some NFS screwups. - -2000-03-03 Jim Meyering - - * regex.m4: Make sure re_compile_pattern accepts patterns like `{1'. - -2000-03-02 Alain Magloire - - * 2.4.1 Release - -2000-02-25 Paul Eggert - - * configure.in (LIBOBJS): Work around automake 1.4 bug: - regex.c wasn't being passed through ansi2knr on pre-ANSI hosts. - (ac_use_included_regex): Fix typo in warning. - * src/Makefile.am (EXTRA_DIST): Remove regex.c, as the LIBOBJS - workaround means that automake now puts regex.c into DIST_COMMON. - -2000-02-25 Alain Magloire - - * po/*.po: update of the PO files. - -2000-02-22 Eli Zaretskii - - * doc/grep.1: Two small glitches(typos). - -2000-02-18 Eli Zaretskii - - * djgpp/config.site (prefix, INSTALL): Use /dev/env/DJDIR instead - of ${DJDIR}, so that the produced Makefile's work on any DJGPP - installation. - -2000-01-30 Alain Magloire - - * doc/grep.1: corrected typo. - Noted by Ruslan Ermilov. - -2000-01-30 Alain Magloire - - * vms/Makefile.am: added config_vms.h to EXTRA_DIST. - * vms/config_vms.h: New File, contains macros specific to VMS and - avoid namespace collision with operating system supplied C library. - * vms/make.com: Better compiler auto-detection; information for builds - on pre-OpenVMS 7.x systems; general overhaul. - * src/getpagesize.h: Reinstate support for different pagesizes on - VAX and Alpha. Work around problem with DEC C compiler. - * src/vms_fab.c: Cast to some assigments; fixed typo argcp vs. argp. - * src/vms_fab.h: Added new include files to avoid warnings about - undefined function prototypes. - Those patches were provided by Martin P.J. Zinser (zinser@decus.de). - -2000-01-30 Paul Eggert - - * src/grep.c (main): Update copyright notice. - -2000-01-28 Alain Magloire - - * src/grep.c (usage): The example "%s -i 'hello.*world' could - lead to confusion when progname is 'fgrep. - Noted by Akim Demaille. - - * configure.in: Reenable, jm_INCLUDE_REGEX() since we now - track GNU lib C. - * src/Makefile.am: EXTRA_DIST new macros with regex.c regex.h. - Requested By Ulrich Drepper. - -2000-01-25 Paul Eggert - - * src/grep.c (grep): If the final byte of an input file is not - a newline, grep now silently supplies one. - * doc/grep.texi, NEWS: Likewise. - -2000-01-25 Paul Eggert - - * NEWS, doc/grep.1, doc/grep.texi: Add -I option. - * src/grep.c (short_options, usage, main): Likewise. - - * doc/grep.texi: Fix some incorrect references to ASCII. - -2000-01-25 Paul Eggert - - * doc/grep.1: Simplify synopsis; sort options; mention - environment variables; clean up some minor gaffes. - -2000-01-25 Paul Eggert - - * doc/grep.texi: - Fix some errors in description of [:print:] and the like. - -2000-01-23 Paul Eggert - - * src/dfa.c (FETCH, lex): Put brackets around if-body to avoid - GCC warning about ambiguous if-then-else. - -2000-01-23 Paul Eggert - - * src/regex.c (GET_UNSIGNED_NUMBER): Allow only ASCII digits. - * src/dfa.c (ISASCIIDIGIT): New macro. - (lex): Use it instead of ISDIGIT. - -2000-01-23 Paul Eggert - - The bug is that regular expression ranges like [a-z] compare raw - byte codes to the range boundaries, whereas POSIX says that they - should use the current collating sequence instead. For example, - in Solaris 7 with LC_ALL=en_US, the command - echo x | grep '[ -~]' - outputs 'x', but it shouldn't output anything since ' ' and '~' - sort before all letters in that locale. - - * src/regex.c (compile_range): When matching a character - range, use the current collating sequence, as POSIX requires. - * src/dfa.c (lex): Likewise. - -2000-01-20 Alain Magloire - - * tests/Makefile.am (dist-hook): Added new rule to make sure - that the shell scripts have the right permissions. - * src/posix/Makefile.am (EXTRA_DIST): added regex.h in the - distribution. - * THANKS: updated. - -2000-01-18 Alain Magloire - - * Rectification the initial patch to add --binary-file option - was done by Ruslan Ermilov. - -2000-01-17 Paul Eggert - - Sync with sources of fileutils 4.0n, tar 1.13.17, glibc 2.1.3a1. - Convert to ANSI C prototypes (using ansi2knr for backwards - compatibility), as this makes it easier to sync. - - * configure.in (AC_OBJEXT): Spell in a funny way, to work around - a bug in automake 1.4 with ansi2knr. - (LIBOBJS): Add assignment so that .o files in LIBOBJS are also built - via the ANSI2KNR-filtering rules. - (AC_OUTPUT): Add src/posix/Makefile. - * src/Makefile.am (AUTOMAKE_OPTIONS): Add ansi2knr. - (SUBDIRS): New macro. - * src/ansi2knr.1, src/ansi2knr.c, src/posix/Makefile.am: New files. - * src/dfa.c, src/dosbuf.c, src/grep.c, src/kwset.c, src/search.c, - src/vms_fab.c: - Use prototypes for function definitions. - * src/grep.c (main): Use int counter for default context, - fixing an ANSI portability bug uncovered by the above changes. - - * config.guess, config.sub, install-sh, missing, src/alloca.c, - src/getpagesize.h, src/memchr.c, src/savedir.c, src/savedir.h, - src/stpcpy.c: - Upgrade to latest version from fileutils 4.0n. - - * src/getopt.c, src/getopt.h, src/getopt1.c: Upgrade to latest - version from tar 1.13.17. - - * src/obstack.c, src/obstack.h, src/regex.c, src/regex.h: - Upgrade to glibc 2.1.3 alpha 1, with K&R C portability fix. - * src/posix/regex.h: New file, from glibc 2.1.3 alpha 1. - -2000-01-04 Paul Eggert - - Initial patch by Ruslan Ermilov. - - Add --binary-files option. - * NEWS, doc/grep.1, doc/grep.texi: Document it. - * src/grep.c (BINARY_FILES_OPTION): New constant. - (long_options, grep, usage, main): New --binary-files option. - (binary_files): New var. - * src/system.h (TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM, CHAR_MAX): - New macros. - (INT_MAX, UCHAR_MAX): Define in terms of TYPE_MAXIMUM. - -2000-01-04 Paul Eggert - - * savedir.c (savedir): Don't store past the end of an array if - name_size is zero and the directory is empty. - Reported by Dima Barsky . - -1999-12-03 Alain Magloire - - * 2.4 Release. - -1999-11-18 Paul Eggert - - * m4/largefile.m4 (AC_SYS_LARGEFILE_FLAGS): Work around a - problem with the QNX 4.25 shell, which doesn't propagate exit - status of failed commands inside shell assignments. - -1999-11-13 Eli Zaretskii - - * doc/grep.texi: Minor markup and spelling corrections. Use - @noindent where appropriate. - - * PATCHES-{AM,AC}: rename to PATCHES.{AM,AC} - -1999-11-12 Eli Zaretskii - - doc/grep.texi: Minor fixes and typos corrected. - djgpp/README: Updated version. - -1999-11-07 Paul Eggert - - * src/grep.c (usage): Fix misspelling. - -1999-11-07 Paul Eggert - - Don't assume that the C library has re_set_syntax and friends. - * src/Makefile.am (base_sources): Add regex.c, regex.h. - (EXTRA_DIST): Remove regex.c, regex.h. - - * src/grep.c (prtext): Use out_quiet, not not_text, to decide - whether to set pending to zero at the end. - (not_text): Remove static variable, undoing latest change. - (grep): Likewise. - - * doc/grep.texi: Tighten up the text, and fix some minor - spelling and usage errors. Use @enumerate rather than @table - @samp, since it's better for Q&A format. Add cross - references. - -1999-11-01 Alain Magloire - - * src/search.c: Use the more portable [[:alnum:]] - to define a word instead of Ascii dependent [0-9A-Za-z] - * src/grep.c: make not_text global to not display text when - the context switches -A/-B/-C are use on binary files. - * make grep-2.3g available for testing. - * configure.in: drop support for --without-included-regex. - This was generating bogus bug reports, since many GNU/Linux - users have different version of glibc. And glibc maintainers - decided to drop k&r support. - -1999-11-01 Arnold D. Robbins - - * regex.c (init_syntax_once): move below definition of - ISALNUM etc., then use ISALNUM to init the table, so that - the word ops will work if i18n'ed. - (SYNTAX): And subscript with 0xFF for Latin-1 characters. - -1999-10-26 Alain Magloire - - * src/regex.c: Merge changes from GNU lib C. - * Updated the *.po files - -1999-10-26 Paul Eggert - - * src/grep.c (fillbuf): Don't report buffer size overflow if - newalloc == save and maxalloc == save. This can happen - e.g. when reading a large page-aligned file that contains - no newlines. - -1999-10-21 Paul Eggert - - * src/grep.c (usage): Give example. Clarify -F. - Explain exit status more clearly. - -1999-10-12 Paul Eggert - - * doc/grep.texi: Shorten the commentary about egrep and {. - "BSD grep" -> "traditional grep". - * doc/grep.1: Match recent changes to grep.texi. - -1999-10-11 Paul Eggert - - * NEWS, doc/grep.1, doc/grep.texi: New option --mmap. - * src/grep.c (mmap_option): New variable. - (long_options, reset, usage): Add --mmap. - Default is now read, not mmap. - - * doc/grep.1: Document -Z or --null. - -1999-10-11 Paul Eggert - - * doc/grep.texi: Fix texinfo glitches. POSIX -> POSIX.2 where - appropriate. - -1999-10-11 Paul Eggert - - * acconfig.h (ssize_t): New #undef. - - * configure.in (AC_CHECK_TYPE): Add ssize_t. - - * src/grep.c (PREFERRED_SAVE_FACTOR): New macro. - (reset): If the buffer has already been allocated, set bufsalloc to - be bufalloc / PREFERRED_SAVE_FACTOR. This avoids problems when - bufsalloc == bufalloc (possible after reading a large binary file). - (reset): Use PREFERRED_SAVE_FACTOR instead of magic constant. - Do not set bufbeg; nobody uses it. - Always set buflim. - Check for lseek error. - Use SEEK_CUR, not a magic constant. - (fillbuf): Return an error indication, not a count. - All callers changed. - Do not assume ssize_t fits in int. - Use PREFERRED_SAVE_FACTOR instead of magic constant. - Clean up mmap code. - Do not attempt to mmap zero bytes. - Check for lseek error. - Use SEEK_SET, not a magic constant. - Work correctly if read is interrupted. - (grepfile): Work correctly if open or close is interrupted. - - * src/system.h (SEEK_SET, SEEK_CUR): New macros. - -1999-10-02 Alain Magloire - - * src/regex.[ch]: upgrade from GNU lib C source tree. - - * make beta 2.3f available. - -1999-10-02 Paul Eggert - - * NEWS: egrep is now equivalent to `grep -E'. - The lower bound of an interval is not optional. - You can specify a matcher multiple types without error. - -u and -U are now allowed on non-DOS hosts, and have no effect. - * doc/grep.texi: Likewise. - * doc/grep.1: Likewise. - Fix some troff bugs that prevented `groff' from rendering the page. - - * src/egrepmat.c, src/fgrepmat.c, src/grepmat.c (default_matcher): - Remove. - (matcher): Add. - * src/grep.h (default_matcher): Remove. - (matcher): Now exported from ?grepmat.c, not grep.c. - - * src/dfa.c (lex): If { would start an invalid interval specification, - treat it as a normal character. - Remove (broken) support for {,M} meaning {0,M}. - Diagnose bogus intervals like {1,0}. - (closure): maxrep is now -1 to indicate no limit, not zero; - zero is a valid value for maxrep, meaning an upper bound of zero. - - * src/grep.c (short_options): New constant. - (long_options, main): -u and -U are now supported on Unix, - with no effect. - (matcher): Removed; now defined by ?grepmat.c. - (install_matcher): Renamed from setmatcher. - (setmatcher): New function. - (usage): Report new, more uniform option scheme. - (main): Do not initialize matcher; ?grepmat.c now does this. - Rely on setmatcher to catch matcher conflicts. - Default matcher is "grep". - - * src/search.c (matchers): - Remove "posix-egrep" matcher; no longer needed. - (Ecompile): Likewise. - The egrep matcher now has POSIX behavior. - - * tests/bre.tests: grep '\{' is no longer an error. - Fix test for interval too large, and enable it. - * tests/ere.tests: grep -E {1 is no longer an error - Likewise for a{1, a{1a, a{1a}, a{1,x}. - -1999-09-22 Paul Eggert - - * largefile.m4 (AC_SYS_LARGEFILE_FLAGS): Work around GCC - 2.95.1 bug with HP-UX 10.20. - -1999-09-12 Paul Eggert - - * src/grep.c (fillbuf): Fix typo: we sometimes reported - arithmetic overflow even when there wasn't any. - -1999-09-12 Paul Eggert - - * configure.in (AC_CHECK_FUNCS): Add memmove. - - * src/system.h (S_ISREG): New macro. - (memmove): Define if ! defined HAVE_MEMMOVE && ! defined memmove, - not if !defined STDC_HEADERS. This is needed for SunOS 4.1.4, - which defines STDC_HEADERS but lacks memmove. - - * src/grep.c (bufoffset): Needed even if !defined HAVE_MMAP. - (reset): Always fstat the file, since we always need its size if it is - regular. - Similarly, get the buffer offset of every regular file. - Set bufmapped to 0 if the file's initial offset is not a multiple - of the page size. - (fillbuf): Calculate an upper bound on how much memory we should - allocate only for regular files, since we don't know the sizes of - other files. - Don't bother to check whether the file offset is a multiple of the page - size, since we now do that just once in `reset'. - When an mmapped area would fall past the end of the file, trim it to - just before instead of giving up immediately and doing a `read'; - that avoids a worst-case behavior that could read half an mmapped file. - Fix bug when computing offsets on hosts that don't have mmap. - -1999-08-27 Paul Eggert - - * src/system.h (memmove): New macro. - - * src/grep.c (page_alloc): Reallocate the old buffer instead - of having both old and new buffers active simultaneously. - Remove valloc debugging variant, which no longer applies. - - (fillbuf): Rejigger the buffer allocation mechanism. The old - mechanism could allocate more than 10*N bytes for an N-byte - file, which was excessive. Check for arithmetic overflow a - bit more carefully. - -1999-08-25 Paul Eggert - - * src/grep.c (grepdir): - Don't assume that st_ino and st_dev must be integers; - POSIX.1 allows them to be floating-point (!). - - * src/vms_fab.h (arr_ptr): `:' -> `;' to fix typo. - -1999-08-18 Alain Magloire - - * 2.3e snapshot. - -1999-08-18 Alain Magloire - - * src/search.c: On a CRAY J90 system running UNICOS 8.0. - Compilation of ./src/search.c failed because the declaration of - the variable "regex": - static struct re_pattern_buffer regex; - conflicted with a previous declaration search.c #includes "system.h", - which #includes , which declares : - extern char *regex __((char *_Re, char *_Subject, ...)); - The declaration in search.c is local to that one source file. - I just changed its name to something less likely to conflict. - (I called it "regexbuf", but you could pick any name you want.) - Excerpt email from Dean Kopesky. - -1999-08-16 Paul Eggert - - Upgrade large-file support to the version used in tar and - textutils. - - * Makefile.am (ACLOCAL_AMFLAGS): Define to be empty. - (M4DIR, ACINCLUDE_INPUTS): New macros. - ($(srcdir)/acinclude.m4): New rule. - - * configure.in (AC_CANONICAL_HOST, AM_C_PROTOTYPES): Add. - (AC_SYS_LARGEFILE): Renamed from AC_LFS, for compatibility - with what should appear in the next autoconf release. - - * m4/largefile.m4: Renamed from m4/lfs.m4. - - * src/ansi2knr.1, src/ansi2knr.c, config.guess, config.sub: - New files. config.guess and config.sub ar needed by the new - AC_SYS_LARGEFILE. ansi2knr is needed by AM_C_PROTOTYPES, - which in turn is needed by the new AC_SYS_LARGEFILE. - -1999-08-16 Alain Magloire - - * 2.3d snapshot on ftp server. - -1999-07-26 Paul Eggert - -Several GNU tools have options to process arbitrary file names, even -file names that contain newline characters. These include `find --print0', `perl -0', `sort -z', and `xargs -0'. It'd be handy if GNU -grep also processed such file names. Here's a proposed patch to do -this, relative to grep 2.3c. This patch introduces two options, one -for the data, and one for the file names. (Sometimes one wants -null-terminated file names in the output, and sometimes one wants to -process lists of null-terminated strings, and these are orthogonal -axes.) - - * NEWS, doc/grep.texi: New -z or --null-data and -Z or --null options. - * src/grep.c (long_options, usage, main): Likewise. - - * src/dfa.h (dfasyntax): New eol parameter. - * src/dfa.c (eolbyte): New var. - (dfasyntax): Set it from new parameter. - (lex, dfastat, build_state, dfaexec): Use it instead of '\n'. - - * src/grep.h (eolbyte): New decl. - * src/grep.c (eolbyte): New var. - (nlscan, prpending, prtext, grepbuf, grep): Use it instead of '\n'. - (filename_mask): New var. - (prline, grepfile): Output NUL separator if filename_mask is zero. - (grep): Look for '\200' as the hallmark of a binary file, not '\0', - if -z or --null-data is specified, since it implies that '\0' is - expected as text. - - * src/search.c (Gcompile, Ecompile): Pass eolbyte to dfasyntax. - (EGexecute, Fexecute): Use eolbyte instead of '\n'. - -1999-06-15 Alain Magloire - - * src/grep.c, doc/grep{1,texi} : - --revert-match should be --invert-match. - Correction proposed by Karl Berry. - -1999-06-12 Alain Magloire - - * doc/grep.{1,texi}: add description for --with-filename. - Noted missing by UEBAYASHI Masao. - -1999-03-17 Paul Eggert - - * NEWS: Add GREP_OPTIONS. - - * doc/grep.texi: Document GREP_OPTIONS, and the other - environment variables. Fix doc for [:blank:], [:cntrl:], [:punct:]. - - * src/grep.c (prepend_args, prepend_default_options): New functions. - (main): Use them to implement GREP_OPTIONS. - * src/system.h (getenv): New decl. - -1999-03-16 Volker Borchert - - * configure.in: Use case case ... esac for checking Visual C++. - When ${CC} contains options it was not recognize. - -1999-03-07 Paul Eggert - - * src/grep.c (usage): Don't report -E, -F, and -G unless we're grep. - (main): Don't match options -E, -F, and -G unless we're grep. - Remove after-the-fact check for options -E, -F, and -G, since - they're no longer needed. - -1999-03-05 Eli Zaretskii - - * src/grep.c (main): Print the name of the default matcher instead - of just "grep". - -1999-02-06 Alain Magloire - - * tests/*.awk : Linux users are seeing "Broken Pipe" on make check. - The problem is that grep does not drain its stdin, thus the previous - process in the pipeline receives a SIGPIPE. Other shells are silent - about this. There is actually no failure, since the broken pipe is - expected. You can work around it by changing the pipeline, so that - the input is drained, like this: - status=`echo 'check' | { ${GREP} -E -e pattern >/dev/null 2>&1; - echo $?; cat >/dev/null; }`; if test $status -ne $errnu then ... fi - Excerpt email from Andreas Schwab. - -1999-02-23 Alain Magloire - - * src/grep.c : Restrict the use of -E, -F, -G - to only grep driver, Posix behaviour. {f,e}grep - the matcher is already set. This change may brake - scripts, warn in NEWS. - - * doc/grep.{1,texi} : -C takes arguments, upgrade manual. - - * beta 2.3a - -1999-02-23 Alain Magloire - - * configure.in : Change the configure VC test from - 'test x$ac_cv_prog_CC = xcl;' to 'test x"$ac_cv_prog_CC" = xcl;' - Email from Joshua R. Poulson. - -1999-02-23 Paul Eggert - - Fix porting bug reported by Amakawa Shuhei for SunOS 4.1.4-JL. - The btowc.c shipped with grep 2.3 is incorrect for Solaris - 2.5.1 and earlier, as it assumes UTF8, which these OSes do not - support. Solaris 7 supports btowc, so there's no need to ship - a substitute for it. The only questionable case is Solaris - 2.6, which lacks btowc but does support UTF8. However, 2.6 - supports UTF8 but only as a demonstration (for an English - locale!); Japanese Solaris 2.6 users typically use EUC, or - sometimes shift-JIS, but they cannot use UTF8 since Japanese - UTF8 is not supported. Hence there's no point to having grep - substitute a btowc that uses UTF8, as it is either redundant, - or it will almost invariably have incorrect behavior. - - * configure.in (AC_CHECK_HEADERS): Don't set USE_WCHAR. - (AC_CHECK_FUNCS): Add btowc, wctype. - (AC_REPLACE_FUNCS): Don't replace btowc; our replacement is - invariably doing the wrong thing anyway, at least on SunOS/Solaris. - Don't bother to check for wctype in -lw, as we don't support - wide characters on Solaris 2.5.1 or earlier anyway. - - * bootstrap/Makefile.try (OBJS): Remove btowc.$(OBJEXT). - - * src/btowc.c: Removed; no longer needed. - -1999-02-19 Paul Eggert - - * NEWS: Fix typo when talking about the old behavior of - silently skipping directories; it was grep 2.1, not grep 2.2. - -1999-02-15 Alain Magloire - - * bootstrap/Makefile.try : add DJGPP DEFS. - Done by Elie Zaretsckii. - -1999-02-14 Alain Magloire - - * m4/gettext.m4 : Guard [] with changequote. - From Elie Zaretskii. - - * djgpp/config.bat : Makefile.in.in --> Makefile.in-in - From Elie Zaretskii. - - * src/dosbuf: k&r function parameter. - - * release of 2.3. - -1999-02-10 Alain Magloire - - * bootstrap/{Makefile{try,am},REAMDE} : skeleton - provided for system lacking the tools to autoconfigure. - - * src/{e,f,}grepmat.c: added guard [HAVE_CONFIG_H] - -1999-02-10 Alain Magloire - - * PATCHES-AC, PATCHES-AM: updated. - - * m4/regex.m4 : updated. - -1999-02-05 Eli Zaretskii - - * m4/gettext.m4 : Support DOS-style D:/foo/bar absolute file - names. - - * aclocal.m4 (DJGPP) : Use $DJ_GPP instead, since changing the - latter prevents GCC from finding headers and libraries. - - * djgpp/config.bat: Make building from another directory work - - * djgpp/config.sed: Remove redundant command wich edited path - separator: now done by configure. - - * src/grep.c [O_BINARY]: Add prototype for undossify_input. - - * doc/grep.texi (Introduction): Typo fixed. - -1999-02-03 Alain Magloire - - * grep-2.2f beta release. - -1999-02-02 Alain Magloire - - * m4/{djgpp,envsep,glibc,regex,dosfile,isc-posix}.m4 : - New files to aid configuration and unload configure.in. - * m4/Makefile.am : updated. - * src/btowc.c : protect for wchar.h - -1999-01-28 Alain Magloire - - * intl/Makefile.in: Replace .o with .${ac_objext} where necessary. - Work around a limitation of Visual C++ on Cygwin32. - * acconfig.h configure.in: Define `alloca' as `_alloca' when CC=cl. - This little hack was suggested by Ian Roxborough . - Patch forwarded by Ben Elliston. - -1999-01-28 Alain Magloire - - * PATCHES-AM: New file. A small patch for automake-1.4, use $(sep) - as the path separator base on @SEP@. - * PATCHES-AC configure.in : updated for autoconf-13. - -1999-01-27 Volker Borchert - - * grep.c: fgrep -NUM not working correctly. - add the argument number to digit_args_val. - -1999-01-22 Paul Eggert - - Prevent grep -r from recursing infinitely through directory loops via - symbolic links. - - * grep.c (struct stats): New type. - (stats_base): New var. - (bufstat): Remove; subsumed by stats->stat. - (reset, fillbuf, grep, grepdir, grepfile): Pass struct stats * arg, - for directory loop checking; use this instead of the bufstat global. - All callers changed. - (grepfile): Stat the file before invoking grepdir. - (grepdir): Assume that the argument has already been statted. - No longer a need for a directory size argument, since it - can be gotten from the struct stats * argument. - Check for directory loops. - Create linked list of directories currently being visited, - to detect loops. - -1998-12-29 Kaveh R. Ghazi - - intl/localealias.c: When building grep-2.2e using cc on Irix4, - I needed the following patch to intl/localealias.c. - (Its the same patch used by fileutils-4.0.) The patch resolves - conflicts between char* and unsigned char* in the i18n code. - -1998-12-10 Alain Magloire - - * src/grep.c : Typo in contex -->context - Noted by Vladimir Michl. - -1998-12-01 Alain Magloire - - * doc/Makefile.am djgpp/Makefile.am m4/Makefile.am vms/Makefile.am: - New files. - - * m4/progtest.m4: proctect '[]' from m4. - Noted by Eli Z. - - * PATCHES-AC: New file, add the patch for autoconf in the dist. - - * acconfig.h: (HAVE_DOS_FILENAME) - - * TODO: updated. - - * src/search.c: remove obsolete 'gegrep,ggrep,gnugrep' - matchers. grep no longer depend on argv[0]. - - * grep-2.2e beta to test DJGPP port. - -1998-11-28 Paul Eggert - - Various portability enhancements: - - Don't assume that O_BINARY implies DOS. Use separate - macros D_OK (for DOS-like directory access) and - HAVE_DOS_FILE_NAMES (for DOS-like file names). - - Don't assume that off_t fits into long; it doesn't on Solaris 2.6. - - Have is_EISDIR set errno properly on hosts with screwed-up EISDIR. - - Treat ':' specially in DOS file names only if it's the end of a - drive specifier. - - Protect against errno < 0. - - * src/grep.c (is_EISDIR): Move defn to system.h. - (print_offset_sep): New function. - (fillbuf): Remove redundant test of O_BINARY. - (totalcc, totalnl): Now of type off_t. - (prline): Use print_offset_sep to print file offsets. - (grepfile): Don't set e to EISDIR; that's is_EISDIR's responsibility - on machines that don't work properly with EISDIR. - (grepdir): Don't assume ':' means slash on all DOS filenames; - it means it only in the file prefix. - - * src/system.h (strerror): Check for negative error numbers. - (is_EISDIR): Depend on D_OK, not O_BINARY. - (SET_BINARY): Depend on HAVE_SETMODE, not __DJGPP__. - (IS_SLASH, FILESYSTEM_PREFIX_LEN): Depend on HAVE_DOS_FILE_NAMES, - not O_BINARY. - (CHAR_BIT): New macro. - - * src/dosbuf.c (struct dos_map): - pos and add members are now of type off_t. - (dos_stripped_crs): Now of type off_t. - (dossified_pos): Now accepts arg and returns value of type off_t. - - * configure.in (AC_CHECK_FUNCS): Add setmode. - (HAVE_DOS_FILENAMES): New macro - -1998-11-27 Eli Zaretskii - - * djgpp/config.sed: New file, a Sed script to edit configure - script before running it on DOS/Windows. - * djgpp/config.bat: Updated to handle po2tbl.sed.in and - po/Makefile.in.in on DOS filesystems, and to run config.sed. - -1998-11-24 Jim Meyering - - * src/grep.c : Typo s/infalid/invalid/ - Also noted by Stanislav Brabec. - -1998-11-24 Eli Zaretskii - - * doc/grep.texi: I found and corrected several typos. - I believe the GNU standards require the section that describes the - options to the programs to be called ``Invoking'' or ``Invoking - ''. This is so users and programs can easily find - that node in any Info file. So I changed the name of the - `Options' chapter to `Invoking', and corrected the - cross-references accordingly. - I added some markup to things like file names and options. - I added some additional index entries where that seemed useful. - I also corrected some index entries, such as "@cindex [:alnum:]", - which used a colon in them (the colons confuse Info readers). - -1998-11-24 Alain Magloire - - * grep/doc/grep.texi : -h is not use for help. - Nit spotted by Jim Meyering. - -1998-11-23 Alain Magloire - - * doc: New directory, grep.1, {e,f}grep.man move here - * doc/grep.texi: New info manual - * doc/version.texi: New - * doc/Makefile.am: New - * tests/{ere,bre}.*: New files. The spencer2 test is split - in two ere/bre. - * config.hin: New, config.h.in rename to config.hin for OS - with limited file system aka DOS. - - * grep-2.2d release for beta. - -1998-11-18 Alain Magloire - - * src/regex.[ch] : Updated from GLibc, previous patches were - integrate by Ulrich Drepper and some added ones. - -1998-11-16 Paul Eggert - - * grep.h (__attribute__): New macro, if not GCC. - (fatal): Add __attribute__((noreturn)). - * grep.c (usage): Add __attribute__((noreturn)). - -1998-11-16 Paul Eggert - - Remove memory leak with valloced buffers, by invoking malloc instead. - - * configure.in (AC_CHECK_FUNCS), src/system.h (valloc): Remove. - * src/grep.c (page_alloc): New function. - (ubuffer, pagesize): New vars. - (ALIGN_TO): New macro. - (reset): Initialize new vars. Check for overflow in buffer size calc. - Use page_alloc instead of valloc. - (fillbuf): Likewise. Use memcpy to copy saved area. - -1998-11-15 Paul Eggert - - * dfa.c (dfacomp), search.c (EGexecute): Don't assume char is unsigned. - -1998-11-14 Paul Eggert - - * src/grep.c (grepdir): Fix bug: memory freed twice. - - * src/search.c (Gcompile, Ecompile): Don't invoke dfainit, - since dfacomp does it for us, and if we also do it then we - leak memory. - -1998-11-13 Eli Zaretskii - - * djgpp/config.bat: Rewrite to run the configure script via Bash. - * djgpp/config.site, djgpp/getconf: New files. - * djgpp/config.h, djgpp/*.mak, djgpp/po2tbl.sed: Remove. - * djgpp/README: Update instructions. - - * Makefile.am (EXTRA_DIST): Update the list of DJGPP files. - - * src/system.h (IS_SLASH): New macro. - (is_EISDIR): Define it here for DOS and Windows. - - * src/grep.c (main) [O_BINARY]: Set stdout to binary mode, so the - EOL formats of the input and output files match, unless stdout is - the console device. - (is_EISDIR): Don't define if already defined. Accept a second - argument, the file name; all callers changed. - (grepdir): Don't free `file', inside the loop. Use IS_SLASH to - check whether `dir' needs a slash. - (grepfile): If file is a directory, set e to EISDIR. - -1998-11-10 Alain Magloire - - * src/vms_fab.{c,h}: New file for VMS wildcard expansion - Written by Phillip C. Brisco. - - * vms/make.com : add line to compile vms_fab.c and - {e,f,}grepmat.c with link for each grep/fgrep/egrep. - Base on patch send by Phillib C. Brisco. - -1998-11-09 Alain Magloire - - * grep-2.2c on alpha for testing. - -1998-11-09 Paul Eggert - - * src/grep.1: Fix `Last Change' of output by generating the date - from the RCS Id. - - * src/grep.c (is_EISDIR): New macro. - (grep): If -s, suppress errors from trying to read directories. - (grepfile): Use is_EISDIR to simplify code. - (grepdir): If -s, suppress errors from trying to read directories. - - * src/grep.1: Fix -q -r -s problems; describe BSD grep better. - - * src/grep.c (main): Update copyright. - - Specify default matcher with default_matcher extern var, not - DEFAULT_MATCHER macro. This is more straightforward and means - we need to compile grep.c just once. - - * src/egrepmat.c, src/fgrepmat.c, src/grepmat.c: New files. - - * src/Makefile.am (base_sources): New macro. - (egrep_SOURCES, fgrep_SOURCES, grep_SOURCES): Now consist of - $(base_sources) plus the single tailoring file. - (grep_LDADD, egrep_LDADD, fgrep_LDADD): Remove. - (EXTRA_DIST): Remove grep.c, regex.c. - (fgrep.o, egrep.o): Remove. - - * src/grep.h (matcher): Now char const *. - (default_matcher): New decl. - - * src/grep.c (matcher): Now char const *. - (setmatcher): Now accepts char const *. - (main): Default the matcher from default_matcher (linked externally) - rather than DEFAULT_MATCHER (a macro). - -1998-11-08 Alain Magloire - - * src/grep.1: `prep.ai.mit.edu' should be replaced with `gnu.org'. - Nit from Paul Eggert. - -1998-11-06 Alain Magloire - - * src/grep.c: The Matcher is not set to argv[0] but - explicitly by a #define MATCHER at compile time default is "grep". - - * aclocal/: NEW dir. provides our own *.m4 - - * configure.in: Move Paul's Large Files to AC_LFS.(aclocal/lfs.m4) - Taken from Jim Meyering fileutils. - -1998-11-05 Alain Magloire - - * src/grep.1: update the man pages according to the - changes make by Miles. - - * po/*.po: updated. - - * first beta release for 2.3 (2.2a). - -1998-11-04 Miles Bader - - * src/grep.c (main): Rationalize interaction of -C/-NUM/-A/-B - options, and allow -C to have an optional argument. -NUM can - now be mixed with -C, and -A, -B always take precedence over - -C/-NUM, regardless of order. - (long_options): Let -C/--context take an optional argument. - -1998-11-03 Alain Magloire - - * src/dfa.c: HP-UX define clrbit/setbit as macros in - #undef if defined. - Fixed by Andreas Ley and Philippe Defert. - - * src/grep.1 : mention that -s follows POSIX.2 behavior. - Noted by Paul Eggert and others. - - * tests/khadafy.sh: a typo in failure(s). - Spotted By Sotiris Vassilopoulos. - -1998-11-01 Paul Eggert - - * src/system.h (IN_CTYPE_DOMAIN): New macro. - (ISALPHA, ISUPPER, ISLOWER, ISDIGIT, ISXDIGIT, ISSPACE, - ISPUNCT, ISALNUM, ISPRINT, ISGRAPH, ISCNTRL): Use - IN_CTYPE_DOMAIN instead of isascii. - -1998-08-18 Paul Eggert - - Add support for new -r or --recursive (or -d recurse or - --directories=recurse) option. - - * src/Makefile.am (grep_SOURCES): Add savedir.c, savedir.h, stpcpy.c. - - * src/grep.1: Describe new options. - - * src/grep.c: Include "savedir.h". - (long_options): Add -r or --recursive. - (RECURSE_DIRECTORIES): New enum value. - (IS_DIRECTORY_ERRNO): Remove. - (reset, grep): Add file name arg. - (grepdir, grepfile): New functions. - (initial_bufoffset): New var. - (reset): Initialize it. - (fillbuf): Use it. - (count_matches, list_files, no_filenames, suppress_errors): New static - vars; formerly were local to `main'. - (grep): Recurse through directories if the user asks for this. - (usage, main): Add new options. - (main): Change some local vars to be static, as described above. - Move most of the guts into grepfile function. - so that it can be recursed through. - - * configure.in (AC_HEADER_DIRENT, AC_FUNC_CLOSEDIR_VOID): Add. - (AC_REPLACE_FUNCS): Add stpcpy. - - * src/savedir.c, src/savedir.h, src/stpcpy.c: New files; - taken from fileutils 3.16u. - -1998-08-11 Paul Eggert - - * src/system.h (initialize_main): New macro. - * src/grep.c (main): Invoke initialize_main first thing. - -1998-04-29 Paul Eggert - - * NEWS, src/grep.1: Describe new -a and -d options. - - * src/grep.c (long_options, usage, main): - New options -d or --directories and -a or --text. - (directories, always_text): New variables. - (IS_DIRECTORY_ERRNO): New macro. - (reset): Now returns value specifying whether to skip this file. - Stat the file if either mmap or directory-skipping is possible. - Skip the file if it's a directory and we're skipping directories. - (grep): Skip the file if `reset' tells us to. - (main): If open fails because the file is a directory, and if we're - skipping directories, don't report an error. - Remove special case for DOS and Windows. - - * src/dosbuf.c (guess_type): Use the same method for guessing whether a - file is binary as grep.c's grep does. - There's no longer any need to declare `bp' to be unsigned. - -1998-04-26 Alain Magloire - - * grep-2.2 release. - - * src/dfa.c: Wrong revision was pulled out - for beta 2.1.1d. - * src/search.c: Wrong revision was pulled out - for beta 2.1.1d. - - * src/grep.c: ck_atoi () added instead of atoi (). - Suggestion from Jim Meyering. - ck_atoi () pulled from diffutils-2.7, maintained by Paul Eggert. - - * AUTHORS: Rephrase of some sentences. - * README: Rewording. - Noted and patched by Joel N. Weber II. - -1998-04-17 Kaveh R. Ghazi - - * src/dfa.h: Don't define `const', trust autoconf to handle it. - -1998-04-16 Alain Magloire - - * tests/{status,empty}.sh: wrong return status. - - * src/grep.c: Remove the REGEX part in usage (), it was - consider overkill by most. - -1998-04-14 Eli Zaretskii - - * djgpp/config.bat: Support file names with multiple dots on all - platforms. - - * djgpp/README: Add instructions about file names illegal on - MS-DOS. - -1998-04-13 Alain Magloire - - * src/dfa.c: by "popular" demand reverse - back to '_' not word-constituent. - - * grep-2.1.1c available for testing. - -1998-04-13 Karl Heuer - - * src/grep.c: (a) The directory check is done too early: - logically, if the argument is "-", then it refers to standard - input, regardless of whether there's something in the file - system answering to "-". - (b) The sh command "grep -l root /etc/passwd /etc/group 0<&-" - prints "(standard input)" instead of "/etc/passwd", because it - mistakenly believes that a named file will never be opened on fd - 0. The string "(standard input)" should be based on the file - having been originally specified as "-", rather than making - assumptions about the fd. - (c) the code that calls close(fd) is being done outside of the - test for a bad fd. Thus, if the open failed, this code will - attempt to close(-1). It should be done inside the "fd != -1" - branch. - This patch addresses all three of these problems. - -1998-04-13 Alain Magloire - - * configure.in: remove the deprecated AC_ISC_POSIX macro. - Spotted by Karl Heuer. - -1998-04-03 Eli Zaretskii - - * djgpp/main.mak, djgpp/src.mak, djgpp/tests.mak: Updated from the - relevant Makefile.in files. - - * djgpp/config.bat: Create files in intl directory like the - configure script does. - -1998-03-28 Eli Zaretskii - - * djgpp/main.mak, djgpp/src.mak, djgpp/tests.mak: Updated to track - changes in respective Makefile.in files. - - * src/dosbuf.c (guess_type): Avoid running off the end of the - buffer. Spotted by Paul Eggert. - -1998-03-27 Alain Magloire - - * grep-2.1.1b.tar.gz available. - - * src/regex.c: CLASS_CHAR_MAX set to 256 instead of 6 - when WCTYPE and WCHAR are not defined. When class names - where bigger then 6, it will not detect an error. - example '[[:alphabet:]]'. - - * Updated the copyright of the files with emacs. - With emacs Jim :). - -1998-03-26 Jim Meyering - - * src/dfa.c (IS_WORD_CONSTITUENT): Define. - (lex): Use IS_WORD_CONSTITUENT, not ISALNUM. - Don't special-case '_'. - (dfastate): Use IS_WORD_CONSTITUENT, not ISALNUM. - (dfaexec): Likewise. - -1998-03-25 Alain Magloire - - * tests/warning.sh: typos and replace the echos with - a simple cat. - Noted By Jim Meyering. - - * src/regex.c: #undef ISASCII and ISPRINT before defining - them(On Solaris it was define). - Pattern 'a[[:]:]]b' is an invalid char class and the error - from regex was 1(REG_NOMATCH) instead of 2 (REG_ECTYPE). - Fix with help from Ulrich Drepper. - - * src/grep.c (usage): Ulrich wrote: "A single printf should - not have more than 900 bytes. For translation reasons the - text shouldn't be split in too many pieces since this is - tiresome and also does not help to generate a consistent picture." - Noted by Ulrich Drepper. - * src/grep.c (usage): Dig out and old patch from - Franc,ois to explain the regex in usage(). - Ideas from Franc,ois Pinard. - -1998-03-23 Alain Magloire - - * testing: grep-2.1.1a for testing. - - * configure.in: Solaris needs '-lw' if we use wchar/wctype - functions. - * src/btowc.c: New file from GNU libc. Solaris 2.5 don't - have it define. - * configure.in : check for btowc (). - - * regex.c: Include before , to work around - a Solaris 2.5 bug. - Patch provided by Paul Eggert. - - * tests/status.sh: new file to check return status code. - * tests/empty.sh: new file to check for empty pattern. - * tests/warning.sh: new file to tell where to report errors. - - * configure.in: If available, prefer support for large files - unless the user specified one of the CPPFLAGS, LDFLAGS, or LIBS - variables. - Done by Paul Eggert. - - * src/grep.c (usage): change prep.ai.mit.edu for gnu.org. - -1998-03-18 Alain Magloire - - * src/grep.c (usage): Formating the --help message a bit off. - Noted by William Bader. - - * src/grep.c (main): When checking conflicting matcher for option -E the - matcher was to "egrep" instead of "posix-egrep". - Reported by kwzh@gnu.org. - - * src/grep.c: Typos and rewording the --help message. - Reported by Karl Heuer. - - * src/grep.1: The man page wording : - A regular expression matching a single character may be - followed by one of several repetition operators: - is unclear since 'x(yz)*z' is a valid regex. - Remove the "matching a single character". - Suggested by Harald Hanche-Olsen. - - * src/grep.c (main): `-f /dev/null' now specifies no patterns - and therfore matches nothing. - Reported by Jorge Stolfi. - Patched by Paul Eggert. - -1998-03-10 Alain Magloire - - * Ice storm 98(el nino). Lost grep repository disk, - and my $HOME directory, etc .. - Trying to get the emails/patch from dejanews.com - and start from grep-2.1. - sigh .... - -1997-11-01 Alain Magloire - - * src/grep.c: For the long options, the problems are: - --file appears in the option table as 'no_argument' - instead of 'required_argument'. - --files-with-matches is missing from the option table. - The help lists '--fixed-strings' as the long option for -F, - the table has '--fixed-regexp'. - --regexp appears in the option table as 'no_argument' - instead of 'required_argument'. - --with-filename is missing from the option table. - Reported by Grant McDorman and Krishna Sethuraman. - -1997-10-19 Alain Magloire - - * src/grep.c: the option "with-filename was not in the arg table. - Corrected by Jim Hand. - - * GNU gettext library from gettext-0.10.32. - - * src/grep.c: reverse back to greping directories, - One could skip the error message by defining - SKIP_DIR_ERROR. There is no clear way of doing - things, I hope to setle this on the next majore release - Thanks Paul Eggert, Eli Zaretskii and gnits for the - exchange. - - * tests/status.sh: add this check to make sure - That the return status code is ok. - -1997-10-10 Andreas Schwab - - * src/grep.1: Fix formatting. - - * configure.in: Check for wctype.h, wchar.h, libintl.h and - isascii, which are needed for regex.c. - -1997-10-01 Paul Eggert - - * src/grep.c (fillbuf): Don't warn about mmap failures. - -1997-09-7 Alain Magloire - - * src/grep.c: added code for -H --with-filename. - - * djgpp/*: patch wrongly apply - duplication of text in djgpp/{README,config.h}. - Filter djgpp/config.bat with unix2dos. - - * djgpp/make.mak: beautify - From Eli Zaretskii. - - * grep-2.1 release. - -1997-09-01 Alain Magloire - - * grep-2.0f out for testing. - - * update to GNU gettext library from gettext-0.10.31 - - * grep.c : have a nicer format for --version. - Noted by Ulrich Drepper. - - * obstack.[ch]: updated from GNU C library - * configure.in: look for stdlib.h [HAVE_STDLIB_H] - Comments from Ulrich Drepper. - -1997-08-25 Philippe De Muyter - - * src/dfa.c (sys/types.h): File included unconditionnaly. - -1997-08-16 Eli Zaretskii - - * grep.c (long_options) [O_BINARY]: Add DOS-specific options. - (fillbuf) [O_BINARY]: For DOS-style text files, strip CR - characters at end of line. - (prline) [O_BINARY]: Report correct byte offsets, even though CR - characters were stripped when reading the file. - (usage) [O_BINARY]: Add DOS-specific options. - (setmatcher) [HAVE_SETRLIMIT]: Set re_max_failures so that the - matcher won't ever overflow the stack. - (main) [__MSDOS__, _WIN32]: Handle backslashes and drive letters - in argv[0], remove the .exe suffix, and downcase the prgram name. - [O_BINARY]: Pass additional DOS-specific options to getopt_long - and handle them. Call stat before attempting to open the file, in - case it is a directory (DOS will fail the open call for - directories). Switch the input descriptor to binary mode, unless - it is a terminal device. - - * system.h [O_BINARY]: Define macros to switch a handle to binary - mode, so binary files could be grep'ed on MS-DOS and MS-Windows. - [HAVE_SETLOCALE]: Test for HAVE_SETLOCALE instead of - HAVE_LC_MESSAGES, to prevent compilation error in grep.c on - systems which don't define HAVE_LC_MESSAGES, but have setlocale. - - * dosbuf.c: New file, functions specific for MS-DOS/MS-Windows. - (guess_type, undossify_input, dossified_pos): New functions. - - * djgpp/config.h, djgpp/config.bat, djgpp/main.mak, djgpp/src.mak, - djgpp/po.mak, djgpp/intl.mak, djgpp/tests.mak, djgpp/po2tbl.sed: - New files, for building Grep with DJGPP tools for MS-DOS and - MS-Windows. - - * grep.1: Document DOS-specific switches. - -1997-08-08 Alain Magloire - - * grep-2.0e: available for testing - - * grep.c: change LC_MESSAGE to LC_ALL for (LC_CTYPE). - Suggested by Jochen Hein. - - * ABOUT-NLS: updated. - * grep.c: --version: more verbosity (COPYRIGHT). - * grep.c: --help: PATTERN, FILE instead of , . - * INSTALL.grep: not necessary removed. - * configure.in: --disable-regex rename --without-include-regex. - * THANKS: format: first row name, second email. - * ChangeLog: format ISO 8601. - Reported by Franc,ois Pinard. - - * grep.c: move dcl of struct stat st into "else" where it's used. - Reported by Jim Meyering. - - * grep.c: totalnl should be %u in printf. - Reported by Michael Aichlmay - Corrected with guidance from Ulrich Drepper - -1997-07-24 Alain Magloire - - * Makefile.am: corrected an error when installing {f,e}grep.1. - From Kaveh R. Ghazi . - From Ulrich Drepper . - - * Many files: use PARAMS instead of __STDC__ for prototypes. - From Jim Meyering . - Patch provided by Kaveh R. Ghazi . - - * dfa.[ch]: uses the one in gawk-3.0.3 with the patch from - Arnold (see Changelog: July 12 1997) - - * grep.1: a note to say -l, -L, -q stop on first match. - Noted by Andrew Beattie . - - * grep.c: refuse to scan if the file is a directory. - This was causing problems on SUNs. If the directory contains - a file that could match the pattern, garbage was display. - - * tests directory: added new set of tests from Henry Spencer - regex package. Change the way the tests were done to be more - conformant to automake. - - * configure.in: added --disable-regex for folks with their own fuctions. - - * grep-20d : available for testing - -1997-07-18 Alain Magloire - - * grep-2.0c: available for testing - -1997-07-17 Alain Magloire - - * src/grep.c: Cause grep to fail if `fclose (stdout)' fails. - From Jim Meyering . - - * grep.c:usage() more consistency in the --help. - - * egrep, fgrep were links This is in violation of GNU standards: - "Please don't make the behavior of a utility depend on the name used - to invoke it. It is useful sometimes to make a link to a utility with - a different name, and that should not change what it does." - For now egrep and fgrep will be copies of grep. A better scheme - should be found later. - After discussion with Tom Tromey . - - * fgrep.man and egrep.man included: They are stubs that call grep.1. - * Makefile.am: modified to install {f,e,}grep[,.1]. - - * speed hack for -l, -L: bail out on first match. - From Scott Weikart . - - * *.[ch]: provided prototypes for strict argument checking - With the help of Stewart Levin . - -1997-07-16 Alain Magloire - - * configure.in: typo in the creation of po/Makefile - Noted by Volker Borchert bt@teknon.de. - - * grep-2.0b: make it available for testing. - -1997-07-15 Alain Magloire - - * src/grep.c usage(): cut the --help in smaller printf()'s - Noted by Ulrich Drepper . - -1997-07-14 Alain Magloire - - * grep-2.0a: make an alpha available for testing. - -1997-07-12 Alain Magloire - - * run gettextize: added the po directory filled with *.po files. - - * check.sh, scriptgen.awk: fix grep paths. - - * change the directory strucure: grep is now in src to comply with - gettext.m4. - - * grep.c version.c [VERSION]: got rid of version.c, - it is now define via config.h. - - * dfa.c: patch to speed up initialization. - Arnold Robbins (arnold@gnu.ai.mit.edu). - -1997-07-09 Alain Magloire - - * *.c [HAVE_CONFIG_H]: Macro defined. - - * support for I18N in Makefile.am and configure.in. - - * update all the string to use gettext(I18N). - Help from Franc,ois Pinard previous patch . - -1997-07-04 Alain Magloire - - * obstack.[ch]: updated from glibc. - Work of Ulrich Drepper . - - * regex.[ch]: updated from glibc. - Work of Ulrich Drepper . - - * grep.c: for option -e not counting '\n' for new keys. - From Mark Waite . - - * grep.c: for option -f allocating the right count. - From Andreas Schwab . - Mike Heartel (mike@cs.uoregon.edu). - - * kwset.c (bmexec): Cast tp[-2] to unsigned char before comparing. - From Jim Meyering . - - * grep.1: various typos. - From Keith Bostic . - Mike Heartel (mike@cs.uoregon.edu). - -1997-06-17 Alain Magloire - - * grep.c: support for long options. - patch done by Franc,ois Pinard . - - * add getopt1.c in Makefile.am. - Noted by Franc,ois Pinard - - * replace getopt.[ch] and add getopt1.c. - - * kwset.c: undef malloc before define it. - Franc,ois Pinard . - -1997-06-07 Alain Magloire - - * grep.c: format incorrect in - fprintf("%s: warning: %s: %s...", filename, strerror(errno)). - Mike Heartel (mike@cs.uoregon.edu). - -1996-11-19 David J MacKenzie - - * make.com: Set the logical SYS. From rdb@cocamrd.oz.au (Rodney Brown). - - * grep.c (S_ISREG): Define if not defined already, for e.g. - SunOS 4.0.3. - - * dfa.c (test_bit, set_bit, clear_bit): Renamed from tstbit, - setbit, clrbit to avoid conflict with HP-UX sys/param.h macros. - - * memchr.c: New file, from GNU libc. - * grep.c (memchr): Remove definition. - * configure.in: Use AC_REPLACE_FUNCS for memchr. - - * configure.in: Remove unused checks for memalign and unsigned char. - * grep.c: HAVE_WORKING_MMAP -> HAVE_MMAP. - - * system.h: New file. - * dfa.c, kwset.c, grep.c, search.c: Use it instead of duplicating - portability boilerplate. - - * grep.c: Include sys/types.h once, instead of three times - conditionally. - * dfa.c, kwset.c, search.c: Include sys/types.h unconditionally, - to always try to get size_t (needed on some old SysV's). - - * dfa.c: Define strchr in terms of index, not the other way around. - * search.c: Use memcpy instead of bcopy. - -1996-11-15 David J MacKenzie - - * Many files: Update FSF address. - Update configuration to use autoconf v2 and automake. - -1993-05-22 Mike Haertel - - * Version 2.0 released. Index: gnu/usr.bin/grep/FREEBSD-upgrade =================================================================== --- gnu/usr.bin/grep/FREEBSD-upgrade +++ /dev/null @@ -1,37 +0,0 @@ -$FreeBSD$ - -GNU grep - -Original source distribution can be found at: - http://ftp.gnu.org/pub/gnu/grep/ - -Due to an unfortunate number of bugs and performance problems in -GNU grep 2.5.1, various patches from The Fedora Project have been applied. -These patches can be extracted from the SRPM package available at: - - http://download.fedora.redhat.com/pub/fedora/linux/core/test/ - 3.92/SRPMS/grep-2.5.1-48.src.rpm - -The following patches have been applied: - - grep-2.5-i18n.patch - grep-2.5.1-bracket.patch - grep-2.5.1-color.patch - grep-2.5.1-dfa-optional.patch - grep-2.5.1-egf-speedup.patch - grep-2.5.1-fgrep.patch - grep-2.5.1-icolor.patch - grep-2.5.1-oi.patch - grep-2.5.1-w.patch - -In addition to these, some FreeBSD-specific changes have been made -to add bzip2 support, etc. - -Due to the large number of patches applied, conflicts are likely with -future releases. However, most of the patches are either (a) small bug -fixes that have been fed upstream, or (b) performance improvements that -could be reverted without loss of functionality. - -It is suggested that those planning to import a newer release of GNU grep -should revert all local changes since the 2.5.1 import before proceeding -with the newer import. Index: gnu/usr.bin/grep/Makefile =================================================================== --- gnu/usr.bin/grep/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# $FreeBSD$ - -.include - -GREP_LIBZ=YES - -.if ${MK_BSD_GREP} != "yes" -PROG= grep -.else -PROG= gnugrep -.endif -SRCS= closeout.c dfa.c error.c exclude.c grep.c grepmat.c hard-locale.c \ - isdir.c kwset.c obstack.c quotearg.c savedir.c search.c xmalloc.c \ - xstrtoumax.c -CLEANFILES+= gnugrep.1 - -WARNS?= 0 - -CFLAGS+=-I${.CURDIR} -I${SYSROOT:U${DESTDIR}}/usr/include/gnu -DHAVE_CONFIG_H - -.if ${MK_BSD_GREP} != "yes" -LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \ - ${BINDIR}/grep ${BINDIR}/fgrep -MLINKS= grep.1 egrep.1 grep.1 fgrep.1 -.endif - -LIBADD= gnuregex bz2 - -.if defined(GREP_LIBZ) && !empty(GREP_LIBZ) -LIBADD+= z -CFLAGS+=-DHAVE_LIBZ=1 -.endif - -gnugrep.1: grep.1 - ${CP} ${.ALLSRC} ${.TARGET} - -check: all - @failed=0; total=0; \ - for tst in ${TESTS}; do \ - total=$$(($$total+1)); \ - if GREP=${.OBJDIR}/${PROG} srcdir=${.CURDIR}/tests \ - ${.CURDIR}/tests/$$tst; then \ - echo "PASS: $$tst"; \ - else \ - failed=$$(($$failed+1)); \ - echo "FAIL: $$tst"; \ - fi; \ - done; \ - if [ "$$failed" -eq 0 ]; then \ - echo "All $$total tests passed"; \ - else \ - echo "$$failed of $$total tests failed"; \ - fi - -TESTS= warning.sh khadafy.sh spencer1.sh bre.sh ere.sh status.sh empty.sh \ - options.sh backref.sh file.sh - -.include Index: gnu/usr.bin/grep/Makefile.depend =================================================================== --- gnu/usr.bin/grep/Makefile.depend +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libregex \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libbz2 \ - lib/libc \ - lib/libcompiler_rt \ - lib/libz \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: gnu/usr.bin/grep/NEWS =================================================================== --- gnu/usr.bin/grep/NEWS +++ /dev/null @@ -1,238 +0,0 @@ -Version 2.5.1 - - This is a bugfix release. No new features. - -Version 2.5 - - The new option --label allows to specify a different name for input - from stdin. See the man or info pages for details. - - - The internal lib/getopt* files are no longer used on systems providing - getopt functionality in their libc (e.g. glibc 2.2.x). - If you need the old getopt files, use --with-included-getopt. - - - The new option --only-matching (-o) will print only the part of matching - lines that matches the pattern. This is useful, for example, to extract - IP addresses from log files. - - - i18n bug fixed ([A-Z0-9] wouldn't match A in locales other than C on - systems using recent glibc builds - - - GNU grep can now be built with autoconf 2.52. - - - The new option --devices controls how grep handles device files. Its usage - is analogous to --directories. - - - The new option --line-buffered fflush on everyline. There is a noticeable - slow down when forcing line buffering. - - - Back references are now local to the regex. - grep -e '\(a\)\1' -e '\(b\)\1' - The last backref \1 in the second expression refer to \(b\) - - - The new option --include=PATTERN will only search matching files - when recursing in directories - - - The new option --exclude=PATTERN will skip matching files when - recursing in directories. - - - The new option --color will use the environment variable GREP_COLOR - (default is red) to highlight the matching string. - --color takes an optional argument specifying when to colorize a line: - --color=always, --color=tty, --color=never - - - The following changes are for POSIX.2 conformance: - - . The -q or --quiet or --silent option now causes grep to exit - with zero status when a input line is selected, even if an error - also occurs. - - . The -s or --no-messages option no longer affects the exit status. - - . Bracket regular expressions like [a-z] are now locale-dependent. - For example, many locales sort characters in dictionary order, - and in these locales the regular expression [a-d] is not - equivalent to [abcd]; it might be equivalent to [aBbCcDd], for - example. To obtain the traditional interpretation of bracket - expressions, you can use the C locale by setting the LC_ALL - environment variable to the value "C". - - - The -C or --context option now requires an argument, partly for - consistency, and partly because POSIX.2 recommends against - optional arguments. - - - The new -P or --perl-regexp option tells grep to interpert the pattern as - a Perl regular expression. - - - The new option --max-count=num makes grep stop reading a file after num - matching lines. - New option -m; equivalent to --max-count. - - - Translations for bg, ca, da, nb and tr have been added. - -Version 2.4.2 - - - Added more check in configure to default the grep-${version}/src/regex.c - instead of the one in GNU Lib C. - -Version 2.4.1 - - - If the final byte of an input file is not a newline, grep now silently - supplies one. - - - The new option --binary-files=TYPE makes grep assume that a binary input - file is of type TYPE. - --binary-files='binary' (the default) outputs a 1-line summary of matches. - --binary-files='without-match' assumes binary files do not match. - --binary-files='text' treats binary files as text - (equivalent to the -a or --text option). - - - New option -I; equivalent to --binary-files='without-match'. - -Version 2.4: - - - egrep is now equivalent to `grep -E' as required by POSIX, - removing a longstanding source of confusion and incompatibility. - `grep' is now more forgiving about stray `{'s, for backward - compatibility with traditional egrep. - - - The lower bound of an interval is not optional. - You must use an explicit zero, e.g. `x{0,10}' instead of `x{,10}'. - (The old documentation incorrectly claimed that it was optional.) - - - The --revert-match option has been renamed to --invert-match. - - - The --fixed-regexp option has been renamed to --fixed-string. - - - New option -H or --with-filename. - - - New option --mmap. By default, GNU grep now uses read instead of mmap. - This is faster on some hosts, and is safer on all. - - - The new option -z or --null-data causes `grep' to treat a zero byte - (the ASCII NUL character) as a line terminator in input data, and - to treat newlines as ordinary data. - - - The new option -Z or --null causes `grep' to output a zero byte - instead of the normal separator after a file name. - - - These two options can be used with commands like `find -print0', - `perl -0', `sort -z', and `xargs -0' to process arbitrary file names, - even those that contain newlines. - - - The environment variable GREP_OPTIONS specifies default options; - e.g. GREP_OPTIONS='--directories=skip' reestablishes grep 2.1's - behavior of silently skipping directories. - - - You can specify a matcher multiple times without error, e.g. - `grep -E -E' or `fgrep -F'. It is still an error to specify - conflicting matchers. - - - -u and -U are now allowed on non-DOS hosts, and have no effect. - - - Modifications of the tests scripts to go around the "Broken Pipe" - errors from bash. See Bash FAQ. - - - New option -r or --recursive or --directories=recurse. - (This option was also in grep 2.3, but wasn't announced here.) - - - --without-included-regex disable, was causing bogus reports .i.e - doing more harm then good. - -Version 2.3: - - - When searching a binary file FOO, grep now just reports - `Binary file FOO matches' instead of outputting binary data. - This is typically more useful than the old behavior, - and it is also more consistent with other utilities like `diff'. - A file is considered to be binary if it contains a NUL (i.e. zero) byte. - - The new -a or --text option causes `grep' to assume that all - input is text. (This option has the same meaning as with `diff'.) - Use it if you want binary data in your output. - - - `grep' now searches directories just like ordinary files; it no longer - silently skips directories. This is the traditional behavior of - Unix text utilities (in particular, of traditional `grep'). - Hence `grep PATTERN DIRECTORY' should report - `grep: DIRECTORY: Is a directory' on hosts where the operating system - does not permit programs to read directories directly, and - `grep: DIRECTORY: Binary file matches' (or nothing) otherwise. - - The new -d ACTION or --directories=ACTION option affects directory handling. - `-d skip' causes `grep' to silently skip directories, as in grep 2.1; - `-d read' (the default) causes `grep' to read directories if possible, - as in earlier versions of grep. - - - The MS-DOS and Microsoft Windows ports now behave identically to the - GNU and Unix ports with respect to binary files and directories. - -Version 2.2: - -Bug fix release. - - - Status error number fix. - - Skipping directories removed. - - Many typos fix. - - -f /dev/null fix(not to consider as an empty pattern). - - Checks for wctype/wchar. - - -E was using the wrong matcher fix. - - bug in regex char class fix - - Fixes for DJGPP - -Version 2.1: - -This is a bug fix release(see Changelog) i.e. no new features. - - - More compliance to GNU standard. - - Long options. - - Internationalisation. - - Use automake/autoconf. - - Directory hierarchy change. - - Sigvec with -e on Linux corrected. - - Sigvec with -f on Linux corrected. - - Sigvec with the mmap() corrected. - - Bug in kwset corrected. - - -q, -L and -l stop on first match. - - New and improve regex.[ch] from Ulrich Drepper. - - New and improve dfa.[ch] from Arnold Robbins. - - Prototypes for over zealous C compiler. - - Not scanning a file, if it's a directory - (cause problems on Sun). - - Ported to MS-DOS/MS-Windows with DJGPP tools. - -See Changelog for the full story and proper credits. - -Version 2.0: - -The most important user visible change is that egrep and fgrep have -disappeared as separate programs into the single grep program mandated -by POSIX 1003.2. New options -G, -E, and -F have been added, -selecting grep, egrep, and fgrep behavior respectively. For -compatibility with historical practice, hard links named egrep and -fgrep are also provided. See the manual page for details. - -In addition, the regular expression facilities described in Posix -draft 11.2 are now supported, except for internationalization features -related to locale-dependent collating sequence information. - -There is a new option, -L, which is like -l except it lists -files which don't contain matches. The reason this option was -added is because '-l -v' doesn't do what you expect. - -Performance has been improved; the amount of improvement is platform -dependent, but (for example) grep 2.0 typically runs at least 30% faster -than grep 1.6 on a DECstation using the MIPS compiler. Where possible, -grep now uses mmap() for file input; on a Sun 4 running SunOS 4.1 this -may cut system time by as much as half, for a total reduction in running -time by nearly 50%. On machines that don't use mmap(), the buffering -code has been rewritten to choose more favorable alignments and buffer -sizes for read(). - -Portability has been substantially cleaned up, and an automatic -configure script is now provided. - -The internals have changed in ways too numerous to mention. -People brave enough to reuse the DFA matcher in other programs -will now have their bravery amply "rewarded", for the interface -to that file has been completely changed. Some changes were -necessary to track the evolution of the regex package, and since -I was changing it anyway I decided to do a general cleanup. Index: gnu/usr.bin/grep/README =================================================================== --- gnu/usr.bin/grep/README +++ /dev/null @@ -1,26 +0,0 @@ -This is GNU grep, the "fastest grep in the west" (we hope). All -bugs reported in previous releases have been fixed. Many exciting new -bugs have probably been introduced in this revision. - -GNU grep is provided "as is" with no warranty. The exact terms -under which you may use and (re)distribute this program are detailed -in the GNU General Public License, in the file COPYING. - -GNU grep is based on a fast lazy-state deterministic matcher (about -twice as fast as stock Unix egrep) hybridized with a Boyer-Moore-Gosper -search for a fixed string that eliminates impossible text from being -considered by the full regexp matcher without necessarily having to -look at every character. The result is typically many times faster -than Unix grep or egrep. (Regular expressions containing backreferencing -will run more slowly, however.) - -See the files AUTHORS and THANKS for a list of authors and other contributors. - -See the file INSTALL for compilation and installation instructions. - -See the file NEWS for a description of major changes in this release. - -See the file TODO for ideas on how you could help us improve grep. - -Send bug reports to bug-gnu-utils@gnu.org. Be sure to -include the word "grep" in your Subject: header field. Index: gnu/usr.bin/grep/THANKS =================================================================== --- gnu/usr.bin/grep/THANKS +++ /dev/null @@ -1,72 +0,0 @@ -Aharon Robbins -Akim Demaille -Alain Magloire -Andreas Schwab -Andreas Ley -Bastiaan "Darquan" Stougie -Ben Elliston -Bernd Strieder -Bernhard Rosenkraenzer -Bob Proulx -Brian Youmans <3diff@gnu.org> -Bruno Haible -Christian Groessler -David Clissold -David J MacKenzie -David O'Brien -Eli Zaretskii -Florian La Roche -Franc,ois Pinard -Gerald Stoller -Grant McDorman -Greg Louis -Guglielmo 'bond' Bondioni -H. Merijn Brand -Harald Hanche-Olsen -Hans-Bernhard Broeker -Heikki Korpela -Isamu Hasegawa -Jeff Bailey -Jim Hand -Jim Meyering -Jochen Hein -Joel N. Weber II -John Hughes -Jorge Stolfi -Juan Manuel Guerrero -Karl Berry -Karl Heuer -Kaveh R. Ghazi -Kazuro Furukawa -Keith Bostic -Krishna Sethuraman -Kurt D Schwehr -Mark Waite -Martin P.J. Zinser -Martin Rex -Michael Aichlmayr -Miles Bader -Olaf Kirch -Paul Eggert -Paul Kimoto -Phillip C. Brisco -Philippe Defert -Philippe De Muyter -Philip Hazel -Roland Roberts -Ruslan Ermilov -Santiago Vila -Shannon Hill -Sotiris Vassilopoulos -Stewart Levin -Sydoruk Stepan -Tapani Tarvainen -Tom 'moof' Spindler -Tom Tromey -Ulrich Drepper -UEBAYASHI Masao -Uwe H. Steinfeld -Volker Borchert -Wichert Akkerman -William Bader -Wolfgang Schludi Index: gnu/usr.bin/grep/closeout.h =================================================================== --- gnu/usr.bin/grep/closeout.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CLOSEOUT_H -# define CLOSEOUT_H 1 - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -void close_stdout_set_status PARAMS ((int status)); -void close_stdout_set_file_name PARAMS ((const char *file)); -void close_stdout PARAMS ((void)); -void close_stdout_status PARAMS ((int status)); - -#endif Index: gnu/usr.bin/grep/closeout.c =================================================================== --- gnu/usr.bin/grep/closeout.c +++ /dev/null @@ -1,121 +0,0 @@ -/* closeout.c - close standard output - Copyright (C) 1998, 1999, 2000, 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define _(Text) Text -#endif - -#if HAVE_STDLIB_H -# include -#endif -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -#include - -#include -#ifndef errno -extern int errno; -#endif - -#include "closeout.h" -#include "error.h" -#include "quotearg.h" -#if 0 -#include "__fpending.h" -#endif - -static int default_exit_status = EXIT_FAILURE; -static const char *file_name; - -/* Set the value to be used for the exit status when close_stdout is called. - This is useful when it is not convenient to call close_stdout_status, - e.g., when close_stdout is called via atexit. */ -void -close_stdout_set_status (int status) -{ - default_exit_status = status; -} - -/* Set the file name to be reported in the event an error is detected - by close_stdout_status. */ -void -close_stdout_set_file_name (const char *file) -{ - file_name = file; -} - -/* Close standard output, exiting with status STATUS on failure. - If a program writes *anything* to stdout, that program should `fflush' - stdout and make sure that it succeeds before exiting. Otherwise, - suppose that you go to the extreme of checking the return status - of every function that does an explicit write to stdout. The last - printf can succeed in writing to the internal stream buffer, and yet - the fclose(stdout) could still fail (due e.g., to a disk full error) - when it tries to write out that buffered data. Thus, you would be - left with an incomplete output file and the offending program would - exit successfully. - - FIXME: note the fflush suggested above is implicit in the fclose - we actually do below. Consider doing only the fflush and/or using - setvbuf to inhibit buffering. - - Besides, it's wasteful to check the return value from every call - that writes to stdout -- just let the internal stream state record - the failure. That's what the ferror test is checking below. - - It's important to detect such failures and exit nonzero because many - tools (most notably `make' and other build-management systems) depend - on being able to detect failure in other tools via their exit status. */ - -void -close_stdout_status (int status) -{ - int e = ferror (stdout) ? 0 : -1; - -#if 0 - if (__fpending (stdout) == 0) - return; -#endif - - if (fclose (stdout) != 0) - e = errno; - - if (0 < e) - { - char const *write_error = _("write error"); - if (file_name) - error (status, e, "%s: %s", quotearg_colon (file_name), write_error); - else - error (status, e, "%s", write_error); - } -} - -/* Close standard output, exiting with status EXIT_FAILURE on failure. */ -void -close_stdout (void) -{ - close_stdout_status (default_exit_status); -} Index: gnu/usr.bin/grep/config.h =================================================================== --- gnu/usr.bin/grep/config.h +++ /dev/null @@ -1,342 +0,0 @@ -/* $FreeBSD$ */ -/* config.h. Generated by configure. */ -/* config.hin. Generated from configure.in by autoheader. */ - -/* Define to 1 if the `closedir' function returns void instead of `int'. */ -/* #undef CLOSEDIR_VOID */ - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -/* #undef CRAY_STACKSEG_END */ - -/* Define to 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -/* #undef ENABLE_NLS */ - -/* We are building grep */ -#define GREP 1 - -/* Define to 1 if you have `alloca', as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define to 1 if you have and it should be used (not on Ultrix). - */ -/* #undef HAVE_ALLOCA_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARGZ_H */ - -/* Define to 1 if you have the `atexit' function. */ -#define HAVE_ATEXIT 1 - -/* Define to 1 if you have the `btowc' function. */ -#define HAVE_BTOWC 1 - -/* Define to 1 if you have the `dcgettext' function. */ -/* #undef HAVE_DCGETTEXT */ - -/* Define to 1 if strerror_r is declared. */ -#define HAVE_DECL_STRERROR_R 1 - -/* Define if declares strtoul. */ -#define HAVE_DECL_STRTOUL 1 - -/* Define if declares strtoull. */ -#define HAVE_DECL_STRTOULL 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#define HAVE_DIRENT_H 1 - -/* Define if the malloc check has been performed. */ -#define HAVE_DONE_WORKING_MALLOC_CHECK 1 - -/* Define if the realloc check has been performed. */ -#define HAVE_DONE_WORKING_REALLOC_CHECK 1 - -/* Define to 1 if you have the `doprnt' function. */ -/* #undef HAVE_DOPRNT */ - -/* Define if text file lines end in CRLF. */ -/* #undef HAVE_DOS_FILE_CONTENTS */ - -/* Define if your OS uses backslashes as directory separators */ -/* #undef HAVE_DOS_FILE_NAMES */ - -/* Define to 1 if you have the `feof_unlocked' function. */ -#define HAVE_FEOF_UNLOCKED 1 - -/* Define to 1 if you have the `fgets_unlocked' function. */ -/* #undef HAVE_FGETS_UNLOCKED */ - -/* Define to 1 if you have the `fnmatch' function. */ -#define HAVE_FNMATCH 1 - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the `getegid' function. */ -#define HAVE_GETEGID 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `getgid' function. */ -#define HAVE_GETGID 1 - -/* Define to 1 if you have the `getpagesize' function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define if the GNU gettext() function is already present or preinstalled. */ -/* #undef HAVE_GETTEXT */ - -/* Define to 1 if you have the `getuid' function. */ -#define HAVE_GETUID 1 - -/* Define if you have the iconv() function. */ -#define HAVE_ICONV 1 - -/* Define if exists, doesn't clash with , and - declares uintmax_t. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `isascii' function. */ -#define HAVE_ISASCII 1 - -/* Define if you have and nl_langinfo(CODESET). */ -#define HAVE_LANGINFO_CODESET 1 - -/* Define if your file defines LC_MESSAGES. */ -#define HAVE_LC_MESSAGES 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBINTL_H */ - -/* Define to 1 if you have the `pcre' library (-lpcre). */ -/* #undef HAVE_LIBPCRE */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MALLOC_H */ - -/* Define to 1 if you have the `mbrtowc' function. */ -#define HAVE_MBRTOWC 1 - -/* Define to 1 if you have the `memchr' function. */ -#define HAVE_MEMCHR 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -/* #undef HAVE_MEMPCPY */ - -/* Define to 1 if you have a working `mmap' system call. */ -#define HAVE_MMAP 1 - -/* Define to 1 if you have the `munmap' function. */ -#define HAVE_MUNMAP 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_NL_TYPES_H 1 - -/* Define to 1 if you have the `putenv' function. */ -#define HAVE_PUTENV 1 - -/* Define to 1 if you have the `setenv' function. */ -#define HAVE_SETENV 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setmode' function. */ -#define HAVE_SETMODE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strchr' function. */ -#define HAVE_STRCHR 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strtoul' function. */ -#define HAVE_STRTOUL 1 - -/* Define to 1 if you have the `strtoull' function. */ -/* #undef HAVE_STRTOULL */ - -/* Define to 1 if you have the `strtoumax' function. */ -#define HAVE_STRTOUMAX 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the `tsearch' function. */ -#define HAVE_TSEARCH 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define if you have the unsigned long long type. */ -#define HAVE_UNSIGNED_LONG_LONG 1 - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCHAR_H 1 - -/* Define to 1 if you have the `wctype' function. */ -#define HAVE_WCTYPE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCTYPE_H 1 - -/* Define to 1 if strerror_r returns a string. */ -/* #undef HAVE_WORKING_STRERROR_R */ - -/* Define to 1 if you have the `__argz_count' function. */ -/* #undef HAVE___ARGZ_COUNT */ - -/* Define to 1 if you have the `__argz_next' function. */ -/* #undef HAVE___ARGZ_NEXT */ - -/* Define to 1 if you have the `__argz_stringify' function. */ -/* #undef HAVE___ARGZ_STRINGIFY */ - -/* Define as const if the declaration of iconv() needs const. */ -#define ICONV_CONST - -/* Name of package */ -#define PACKAGE "grep" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define if compiler has function prototypes */ -#define PROTOTYPES 1 - -/* If using the C implementation of alloca, define 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 */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if the `S_IS*' macros in do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "2.5.1-FreeBSD" - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define to make fseeko etc. visible, on some hosts. */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define if your compiler is broken */ -/* #undef alloca */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define as `__inline' if that's what the C compiler calls it, or to nothing - if it is not supported. */ -/* #undef inline */ - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to a type if does not define. */ -/* #undef mbstate_t */ - -/* Define to `long' if does not define. */ -/* #undef off_t */ - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to `unsigned' if does not define. */ -/* #undef size_t */ - -/* Define to `int' if does not define. */ -/* #undef ssize_t */ - -/* Define to unsigned long or unsigned long long if doesn't - define. */ -/* #undef uintmax_t */ Index: gnu/usr.bin/grep/dfa.h =================================================================== --- gnu/usr.bin/grep/dfa.h +++ /dev/null @@ -1,434 +0,0 @@ -/* dfa.h - declarations for GNU deterministic regexp compiler - Copyright (C) 1988, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ - -/* Written June, 1988 by Mike Haertel */ - -/* $FreeBSD$ */ - -/* FIXME: - 2. We should not export so much of the DFA internals. - In addition to clobbering modularity, we eat up valuable - name space. */ - -#ifdef __STDC__ -# ifndef _PTR_T -# define _PTR_T - typedef void * ptr_t; -# endif -#else -# ifndef _PTR_T -# define _PTR_T - typedef char * ptr_t; -# endif -#endif - -#ifdef PARAMS -# undef PARAMS -#endif -#if PROTOTYPES -# define PARAMS(x) x -#else -# define PARAMS(x) () -#endif - -/* Number of bits in an unsigned char. */ -#ifndef CHARBITS -#define CHARBITS 8 -#endif - -/* First integer value that is greater than any character code. */ -#define NOTCHAR (1 << CHARBITS) - -/* INTBITS need not be exact, just a lower bound. */ -#ifndef INTBITS -#define INTBITS (CHARBITS * sizeof (int)) -#endif - -/* Number of ints required to hold a bit for every character. */ -#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS) - -/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */ -typedef int charclass[CHARCLASS_INTS]; - -/* The regexp is parsed into an array of tokens in postfix form. Some tokens - are operators and others are terminal symbols. Most (but not all) of these - codes are returned by the lexical analyzer. */ - -typedef enum -{ - END = -1, /* END is a terminal symbol that matches the - end of input; any value of END or less in - the parse tree is such a symbol. Accepting - states of the DFA are those that would have - a transition on END. */ - - /* Ordinary character values are terminal symbols that match themselves. */ - - EMPTY = NOTCHAR, /* EMPTY is a terminal symbol that matches - the empty string. */ - - BACKREF, /* BACKREF is generated by \; it - it not completely handled. If the scanner - detects a transition on backref, it returns - a kind of "semi-success" indicating that - the match will have to be verified with - a backtracking matcher. */ - - BEGLINE, /* BEGLINE is a terminal symbol that matches - the empty string if it is at the beginning - of a line. */ - - ENDLINE, /* ENDLINE is a terminal symbol that matches - the empty string if it is at the end of - a line. */ - - BEGWORD, /* BEGWORD is a terminal symbol that matches - the empty string if it is at the beginning - of a word. */ - - ENDWORD, /* ENDWORD is a terminal symbol that matches - the empty string if it is at the end of - a word. */ - - LIMWORD, /* LIMWORD is a terminal symbol that matches - the empty string if it is at the beginning - or the end of a word. */ - - NOTLIMWORD, /* NOTLIMWORD is a terminal symbol that - matches the empty string if it is not at - the beginning or end of a word. */ - - QMARK, /* QMARK is an operator of one argument that - matches zero or one occurences of its - argument. */ - - STAR, /* STAR is an operator of one argument that - matches the Kleene closure (zero or more - occurrences) of its argument. */ - - PLUS, /* PLUS is an operator of one argument that - matches the positive closure (one or more - occurrences) of its argument. */ - - REPMN, /* REPMN is a lexical token corresponding - to the {m,n} construct. REPMN never - appears in the compiled token vector. */ - - CAT, /* CAT is an operator of two arguments that - matches the concatenation of its - arguments. CAT is never returned by the - lexical analyzer. */ - - OR, /* OR is an operator of two arguments that - matches either of its arguments. */ - - ORTOP, /* OR at the toplevel in the parse tree. - This is used for a boyer-moore heuristic. */ - - LPAREN, /* LPAREN never appears in the parse tree, - it is only a lexeme. */ - - RPAREN, /* RPAREN never appears in the parse tree. */ - - CRANGE, /* CRANGE never appears in the parse tree. - It stands for a character range that can - match a string of one or more characters. - For example, [a-z] can match "ch" in - a Spanish locale. */ - -#ifdef MBS_SUPPORT - ANYCHAR, /* ANYCHAR is a terminal symbol that matches - any multibyte(or singlebyte) characters. - It is used only if MB_CUR_MAX > 1. */ - - MBCSET, /* MBCSET is similar to CSET, but for - multibyte characters. */ -#endif /* MBS_SUPPORT */ - - CSET /* CSET and (and any value greater) is a - terminal symbol that matches any of a - class of characters. */ -} token; - -/* Sets are stored in an array in the compiled dfa; the index of the - array corresponding to a given set token is given by SET_INDEX(t). */ -#define SET_INDEX(t) ((t) - CSET) - -/* Sometimes characters can only be matched depending on the surrounding - context. Such context decisions depend on what the previous character - was, and the value of the current (lookahead) character. Context - dependent constraints are encoded as 8 bit integers. Each bit that - is set indicates that the constraint succeeds in the corresponding - context. - - bit 7 - previous and current are newlines - bit 6 - previous was newline, current isn't - bit 5 - previous wasn't newline, current is - bit 4 - neither previous nor current is a newline - bit 3 - previous and current are word-constituents - bit 2 - previous was word-constituent, current isn't - bit 1 - previous wasn't word-constituent, current is - bit 0 - neither previous nor current is word-constituent - - Word-constituent characters are those that satisfy isalnum(). - - The macro SUCCEEDS_IN_CONTEXT determines whether a a given constraint - succeeds in a particular context. Prevn is true if the previous character - was a newline, currn is true if the lookahead character is a newline. - Prevl and currl similarly depend upon whether the previous and current - characters are word-constituent letters. */ -#define MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \ - ((constraint) & 1 << (((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4)) -#define MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \ - ((constraint) & 1 << (((prevl) ? 2 : 0) + ((currl) ? 1 : 0))) -#define SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \ - (MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \ - && MATCHES_LETTER_CONTEXT(constraint, prevl, currl)) - -/* The following macros give information about what a constraint depends on. */ -#define PREV_NEWLINE_DEPENDENT(constraint) \ - (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30)) -#define PREV_LETTER_DEPENDENT(constraint) \ - (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03)) - -/* Tokens that match the empty string subject to some constraint actually - work by applying that constraint to determine what may follow them, - taking into account what has gone before. The following values are - the constraints corresponding to the special tokens previously defined. */ -#define NO_CONSTRAINT 0xff -#define BEGLINE_CONSTRAINT 0xcf -#define ENDLINE_CONSTRAINT 0xaf -#define BEGWORD_CONSTRAINT 0xf2 -#define ENDWORD_CONSTRAINT 0xf4 -#define LIMWORD_CONSTRAINT 0xf6 -#define NOTLIMWORD_CONSTRAINT 0xf9 - -/* States of the recognizer correspond to sets of positions in the parse - tree, together with the constraints under which they may be matched. - So a position is encoded as an index into the parse tree together with - a constraint. */ -typedef struct -{ - unsigned index; /* Index into the parse array. */ - unsigned constraint; /* Constraint for matching this position. */ -} position; - -/* Sets of positions are stored as arrays. */ -typedef struct -{ - position *elems; /* Elements of this position set. */ - int nelem; /* Number of elements in this set. */ -} position_set; - -/* A state of the dfa consists of a set of positions, some flags, - and the token value of the lowest-numbered position of the state that - contains an END token. */ -typedef struct -{ - int hash; /* Hash of the positions of this state. */ - position_set elems; /* Positions this state could match. */ - char newline; /* True if previous state matched newline. */ - char letter; /* True if previous state matched a letter. */ - char backref; /* True if this state matches a \. */ - unsigned char constraint; /* Constraint for this state to accept. */ - int first_end; /* Token value of the first END in elems. */ -#ifdef MBS_SUPPORT - position_set mbps; /* Positions which can match multibyte - characters. e.g. period. - These staff are used only if - MB_CUR_MAX > 1. */ -#endif -} dfa_state; - -/* Element of a list of strings, at least one of which is known to - appear in any R.E. matching the DFA. */ -struct dfamust -{ - int exact; - char *must; - struct dfamust *next; -}; - -#ifdef MBS_SUPPORT -/* A bracket operator. - e.g. [a-c], [[:alpha:]], etc. */ -struct mb_char_classes -{ - int invert; - wchar_t *chars; /* Normal characters. */ - int nchars; - wctype_t *ch_classes; /* Character classes. */ - int nch_classes; - wchar_t *range_sts; /* Range characters (start of the range). */ - wchar_t *range_ends; /* Range characters (end of the range). */ - int nranges; - char **equivs; /* Equivalent classes. */ - int nequivs; - char **coll_elems; - int ncoll_elems; /* Collating elements. */ -}; -#endif - -/* A compiled regular expression. */ -struct dfa -{ - /* Stuff built by the scanner. */ - charclass *charclasses; /* Array of character sets for CSET tokens. */ - int cindex; /* Index for adding new charclasses. */ - int calloc; /* Number of charclasses currently allocated. */ - - /* Stuff built by the parser. */ - token *tokens; /* Postfix parse array. */ - int tindex; /* Index for adding new tokens. */ - int talloc; /* Number of tokens currently allocated. */ - int depth; /* Depth required of an evaluation stack - used for depth-first traversal of the - parse tree. */ - int nleaves; /* Number of leaves on the parse tree. */ - int nregexps; /* Count of parallel regexps being built - with dfaparse(). */ -#ifdef MBS_SUPPORT - /* These stuff are used only if MB_CUR_MAX > 1 or multibyte environments. */ - int nmultibyte_prop; - int *multibyte_prop; - /* The value of multibyte_prop[i] is defined by following rule. - if tokens[i] < NOTCHAR - bit 1 : tokens[i] is a singlebyte character, or the last-byte of - a multibyte character. - bit 0 : tokens[i] is a singlebyte character, or the 1st-byte of - a multibyte character. - if tokens[i] = MBCSET - ("the index of mbcsets correspnd to this operator" << 2) + 3 - - e.g. - tokens - = 'single_byte_a', 'multi_byte_A', single_byte_b' - = 'sb_a', 'mb_A(1st byte)', 'mb_A(2nd byte)', 'mb_A(3rd byte)', 'sb_b' - multibyte_prop - = 3 , 1 , 0 , 2 , 3 - */ - - /* Array of the bracket expressoin in the DFA. */ - struct mb_char_classes *mbcsets; - int nmbcsets; - int mbcsets_alloc; -#endif - - /* Stuff owned by the state builder. */ - dfa_state *states; /* States of the dfa. */ - int sindex; /* Index for adding new states. */ - int salloc; /* Number of states currently allocated. */ - - /* Stuff built by the structure analyzer. */ - position_set *follows; /* Array of follow sets, indexed by position - index. The follow of a position is the set - of positions containing characters that - could conceivably follow a character - matching the given position in a string - matching the regexp. Allocated to the - maximum possible position index. */ - int searchflag; /* True if we are supposed to build a searching - as opposed to an exact matcher. A searching - matcher finds the first and shortest string - matching a regexp anywhere in the buffer, - whereas an exact matcher finds the longest - string matching, but anchored to the - beginning of the buffer. */ - - /* Stuff owned by the executor. */ - int tralloc; /* Number of transition tables that have - slots so far. */ - int trcount; /* Number of transition tables that have - actually been built. */ - int **trans; /* Transition tables for states that can - never accept. If the transitions for a - state have not yet been computed, or the - state could possibly accept, its entry in - this table is NULL. */ - int **realtrans; /* Trans always points to realtrans + 1; this - is so trans[-1] can contain NULL. */ - int **fails; /* Transition tables after failing to accept - on a state that potentially could do so. */ - int *success; /* Table of acceptance conditions used in - dfaexec and computed in build_state. */ - struct dfamust *musts; /* List of strings, at least one of which - is known to appear in any r.e. matching - the dfa. */ -}; - -/* Some macros for user access to dfa internals. */ - -/* ACCEPTING returns true if s could possibly be an accepting state of r. */ -#define ACCEPTING(s, r) ((r).states[s].constraint) - -/* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the - specified context. */ -#define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, dfa) \ - SUCCEEDS_IN_CONTEXT((dfa).states[state].constraint, \ - prevn, currn, prevl, currl) - -/* FIRST_MATCHING_REGEXP returns the index number of the first of parallel - regexps that a given state could accept. Parallel regexps are numbered - starting at 1. */ -#define FIRST_MATCHING_REGEXP(state, dfa) (-(dfa).states[state].first_end) - -/* Entry points. */ - -/* dfasyntax() takes three arguments; the first sets the syntax bits described - earlier in this file, the second sets the case-folding flag, and the - third specifies the line terminator. */ -extern void dfasyntax PARAMS ((reg_syntax_t, int, unsigned char)); - -/* Compile the given string of the given length into the given struct dfa. - Final argument is a flag specifying whether to build a searching or an - exact matcher. */ -extern void dfacomp PARAMS ((char const *, size_t, struct dfa *, int)); - -/* Execute the given struct dfa on the buffer of characters. The - last byte of the buffer must equal the end-of-line byte. - The final argument points to a flag that will - be set if further examination by a backtracking matcher is needed in - order to verify backreferencing; otherwise the flag will be cleared. - Returns (size_t) -1 if no match is found, or the offset of the first - character after the first & shortest matching string in the buffer. */ -extern size_t dfaexec PARAMS ((struct dfa *, char const *, size_t, int *)); - -/* Free the storage held by the components of a struct dfa. */ -extern void dfafree PARAMS ((struct dfa *)); - -/* Entry points for people who know what they're doing. */ - -/* Initialize the components of a struct dfa. */ -extern void dfainit PARAMS ((struct dfa *)); - -/* Incrementally parse a string of given length into a struct dfa. */ -extern void dfaparse PARAMS ((char const *, size_t, struct dfa *)); - -/* Analyze a parsed regexp; second argument tells whether to build a searching - or an exact matcher. */ -extern void dfaanalyze PARAMS ((struct dfa *, int)); - -/* Compute, for each possible character, the transitions out of a given - state, storing them in an array of integers. */ -extern void dfastate PARAMS ((int, struct dfa *, int [])); - -/* Error handling. */ - -/* dfaerror() is called by the regexp routines whenever an error occurs. It - takes a single argument, a NUL-terminated string describing the error. - The user must supply a dfaerror. */ -extern void dfaerror PARAMS ((const char *)); Index: gnu/usr.bin/grep/dfa.c =================================================================== --- gnu/usr.bin/grep/dfa.c +++ /dev/null @@ -1,3586 +0,0 @@ -/* dfa.c - deterministic extended regexp routines for GNU - Copyright 1988, 1998, 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ - -/* Written June, 1988 by Mike Haertel - Modified July, 1988 by Arthur David Olson to assist BMG speedups */ - -/* $FreeBSD$ */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include -#ifdef STDC_HEADERS -#include -#else -extern char *calloc(), *malloc(), *realloc(); -extern void free(); -#endif - -#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) -#include -#else -#include -#endif - -#if HAVE_SETLOCALE -# include -#endif - -#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC -/* We can handle multibyte string. */ -# define MBS_SUPPORT -#endif - -#ifdef MBS_SUPPORT -# include -# include -#endif - -#ifndef DEBUG /* use the same approach as regex.c */ -#undef assert -#define assert(e) -#endif /* DEBUG */ - -#ifndef isgraph -#define isgraph(C) (isprint(C) && !isspace(C)) -#endif - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -#define ISALPHA(C) isalpha(C) -#define ISUPPER(C) isupper(C) -#define ISLOWER(C) islower(C) -#define ISDIGIT(C) isdigit(C) -#define ISXDIGIT(C) isxdigit(C) -#define ISSPACE(C) isspace(C) -#define ISPUNCT(C) ispunct(C) -#define ISALNUM(C) isalnum(C) -#define ISPRINT(C) isprint(C) -#define ISGRAPH(C) isgraph(C) -#define ISCNTRL(C) iscntrl(C) -#else -#define ISALPHA(C) (isascii(C) && isalpha(C)) -#define ISUPPER(C) (isascii(C) && isupper(C)) -#define ISLOWER(C) (isascii(C) && islower(C)) -#define ISDIGIT(C) (isascii(C) && isdigit(C)) -#define ISXDIGIT(C) (isascii(C) && isxdigit(C)) -#define ISSPACE(C) (isascii(C) && isspace(C)) -#define ISPUNCT(C) (isascii(C) && ispunct(C)) -#define ISALNUM(C) (isascii(C) && isalnum(C)) -#define ISPRINT(C) (isascii(C) && isprint(C)) -#define ISGRAPH(C) (isascii(C) && isgraph(C)) -#define ISCNTRL(C) (isascii(C) && iscntrl(C)) -#endif - -/* ISASCIIDIGIT differs from ISDIGIT, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char. - - It's guaranteed to evaluate its argument exactly once. - - It's typically faster. - Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that - only '0' through '9' are digits. Prefer ISASCIIDIGIT to ISDIGIT unless - it's important to use the locale's definition of `digit' even when the - host does not conform to Posix. */ -#define ISASCIIDIGIT(c) ((unsigned) (c) - '0' <= 9) - -/* If we (don't) have I18N. */ -/* glibc defines _ */ -#ifndef _ -# ifdef HAVE_LIBINTL_H -# include -# ifndef _ -# define _(Str) gettext (Str) -# endif -# else -# define _(Str) (Str) -# endif -#endif - -#include "regex.h" -#include "dfa.h" -#include "hard-locale.h" - -/* HPUX, define those as macros in sys/param.h */ -#ifdef setbit -# undef setbit -#endif -#ifdef clrbit -# undef clrbit -#endif - -static void dfamust PARAMS ((struct dfa *dfa)); -static void regexp PARAMS ((int toplevel)); - -static ptr_t -xcalloc (size_t n, size_t s) -{ - ptr_t r = calloc(n, s); - - if (!r) - dfaerror(_("Memory exhausted")); - return r; -} - -static ptr_t -xmalloc (size_t n) -{ - ptr_t r = malloc(n); - - assert(n != 0); - if (!r) - dfaerror(_("Memory exhausted")); - return r; -} - -static ptr_t -xrealloc (ptr_t p, size_t n) -{ - ptr_t r = realloc(p, n); - - assert(n != 0); - if (!r) - dfaerror(_("Memory exhausted")); - return r; -} - -#define CALLOC(p, t, n) ((p) = (t *) xcalloc((size_t)(n), sizeof (t))) -#define MALLOC(p, t, n) ((p) = (t *) xmalloc((n) * sizeof (t))) -#define REALLOC(p, t, n) ((p) = (t *) xrealloc((ptr_t) (p), (n) * sizeof (t))) - -/* Reallocate an array of type t if nalloc is too small for index. */ -#define REALLOC_IF_NECESSARY(p, t, nalloc, index) \ - if ((index) >= (nalloc)) \ - { \ - do \ - (nalloc) *= 2; \ - while ((index) >= (nalloc)); \ - REALLOC(p, t, nalloc); \ - } - -#ifdef DEBUG - -static void -prtok (token t) -{ - char const *s; - - if (t < 0) - fprintf(stderr, "END"); - else if (t < NOTCHAR) - fprintf(stderr, "%c", t); - else - { - switch (t) - { - case EMPTY: s = "EMPTY"; break; - case BACKREF: s = "BACKREF"; break; - case BEGLINE: s = "BEGLINE"; break; - case ENDLINE: s = "ENDLINE"; break; - case BEGWORD: s = "BEGWORD"; break; - case ENDWORD: s = "ENDWORD"; break; - case LIMWORD: s = "LIMWORD"; break; - case NOTLIMWORD: s = "NOTLIMWORD"; break; - case QMARK: s = "QMARK"; break; - case STAR: s = "STAR"; break; - case PLUS: s = "PLUS"; break; - case CAT: s = "CAT"; break; - case OR: s = "OR"; break; - case ORTOP: s = "ORTOP"; break; - case LPAREN: s = "LPAREN"; break; - case RPAREN: s = "RPAREN"; break; - case CRANGE: s = "CRANGE"; break; -#ifdef MBS_SUPPORT - case ANYCHAR: s = "ANYCHAR"; break; - case MBCSET: s = "MBCSET"; break; -#endif /* MBS_SUPPORT */ - default: s = "CSET"; break; - } - fprintf(stderr, "%s", s); - } -} -#endif /* DEBUG */ - -/* Stuff pertaining to charclasses. */ - -static int -tstbit (unsigned b, charclass c) -{ - return c[b / INTBITS] & 1 << b % INTBITS; -} - -static void -setbit (unsigned b, charclass c) -{ - c[b / INTBITS] |= 1 << b % INTBITS; -} - -static void -clrbit (unsigned b, charclass c) -{ - c[b / INTBITS] &= ~(1 << b % INTBITS); -} - -static void -copyset (charclass src, charclass dst) -{ - memcpy (dst, src, sizeof (charclass)); -} - -static void -zeroset (charclass s) -{ - memset (s, 0, sizeof (charclass)); -} - -static void -notset (charclass s) -{ - int i; - - for (i = 0; i < CHARCLASS_INTS; ++i) - s[i] = ~s[i]; -} - -static int -equal (charclass s1, charclass s2) -{ - return memcmp (s1, s2, sizeof (charclass)) == 0; -} - -/* A pointer to the current dfa is kept here during parsing. */ -static struct dfa *dfa; - -/* Find the index of charclass s in dfa->charclasses, or allocate a new charclass. */ -static int -charclass_index (charclass s) -{ - int i; - - for (i = 0; i < dfa->cindex; ++i) - if (equal(s, dfa->charclasses[i])) - return i; - REALLOC_IF_NECESSARY(dfa->charclasses, charclass, dfa->calloc, dfa->cindex); - ++dfa->cindex; - copyset(s, dfa->charclasses[i]); - return i; -} - -/* Syntax bits controlling the behavior of the lexical analyzer. */ -static reg_syntax_t syntax_bits, syntax_bits_set; - -/* Flag for case-folding letters into sets. */ -static int case_fold; - -/* End-of-line byte in data. */ -static unsigned char eolbyte; - -/* Entry point to set syntax options. */ -void -dfasyntax (reg_syntax_t bits, int fold, unsigned char eol) -{ - syntax_bits_set = 1; - syntax_bits = bits; - case_fold = fold; - eolbyte = eol; -} - -/* Like setbit, but if case is folded, set both cases of a letter. */ -static void -setbit_case_fold (unsigned b, charclass c) -{ - setbit (b, c); - if (case_fold) - { - if (ISUPPER (b)) - setbit (tolower (b), c); - else if (ISLOWER (b)) - setbit (toupper (b), c); - } -} - -/* Lexical analyzer. All the dross that deals with the obnoxious - GNU Regex syntax bits is located here. The poor, suffering - reader is referred to the GNU Regex documentation for the - meaning of the @#%!@#%^!@ syntax bits. */ - -static char const *lexstart; /* Pointer to beginning of input string. */ -static char const *lexptr; /* Pointer to next input character. */ -static int lexleft; /* Number of characters remaining. */ -static token lasttok; /* Previous token returned; initially END. */ -static int laststart; /* True if we're separated from beginning or (, | - only by zero-width characters. */ -static int parens; /* Count of outstanding left parens. */ -static int minrep, maxrep; /* Repeat counts for {m,n}. */ -static int hard_LC_COLLATE; /* Nonzero if LC_COLLATE is hard. */ - -#ifdef MBS_SUPPORT -/* These variables are used only if (MB_CUR_MAX > 1). */ -static mbstate_t mbs; /* Mbstate for mbrlen(). */ -static ssize_t cur_mb_len; /* Byte length of the current scanning - multibyte character. Must also handle - negative result from mbrlen(). */ -static ssize_t cur_mb_index; /* Byte index of the current scanning multibyte - character. - - singlebyte character : cur_mb_index = 0 - multibyte character - 1st byte : cur_mb_index = 1 - 2nd byte : cur_mb_index = 2 - ... - nth byte : cur_mb_index = n */ -static unsigned char *mblen_buf;/* Correspond to the input buffer in dfaexec(). - Each element store the amount of remain - byte of corresponding multibyte character - in the input string. A element's value - is 0 if corresponding character is a - singlebyte chracter. - e.g. input : 'a', , , - mblen_buf : 0, 3, 2, 1 - */ -static wchar_t *inputwcs; /* Wide character representation of input - string in dfaexec(). - The length of this array is same as - the length of input string(char array). - inputstring[i] is a single-byte char, - or 1st byte of a multibyte char. - And inputwcs[i] is the codepoint. */ -static unsigned char const *buf_begin;/* refference to begin in dfaexec(). */ -static unsigned char const *buf_end; /* refference to end in dfaexec(). */ -#endif /* MBS_SUPPORT */ - -#ifdef MBS_SUPPORT -/* This function update cur_mb_len, and cur_mb_index. - p points current lexptr, len is the remaining buffer length. */ -static void -update_mb_len_index (unsigned char const *p, size_t len) -{ - /* If last character is a part of a multibyte character, - we update cur_mb_index. */ - if (cur_mb_index) - cur_mb_index = (cur_mb_index >= cur_mb_len)? 0 - : cur_mb_index + 1; - - /* If last character is a single byte character, or the - last portion of a multibyte character, we check whether - next character is a multibyte character or not. */ - if (! cur_mb_index) - { - cur_mb_len = mbrlen(p, len, &mbs); - if (cur_mb_len > 1) - /* It is a multibyte character. - cur_mb_len was already set by mbrlen(). */ - cur_mb_index = 1; - else if (cur_mb_len < 1) - /* Invalid sequence. We treat it as a singlebyte character. - cur_mb_index is aleady 0. */ - cur_mb_len = 1; - /* Otherwise, cur_mb_len == 1, it is a singlebyte character. - cur_mb_index is aleady 0. */ - } -} -#endif /* MBS_SUPPORT */ - -#ifdef MBS_SUPPORT -/* Note that characters become unsigned here. */ -# define FETCH(c, eoferr) \ - { \ - if (! lexleft) \ - { \ - if (eoferr != 0) \ - dfaerror (eoferr); \ - else \ - return lasttok = END; \ - } \ - if (MB_CUR_MAX > 1) \ - update_mb_len_index(lexptr, lexleft); \ - (c) = (unsigned char) *lexptr++; \ - --lexleft; \ - } - -/* This function fetch a wide character, and update cur_mb_len, - used only if the current locale is a multibyte environment. */ -static wint_t -fetch_wc (char const *eoferr) -{ - wchar_t wc; - if (! lexleft) - { - if (eoferr != 0) - dfaerror (eoferr); - else - return WEOF; - } - - cur_mb_len = mbrtowc(&wc, lexptr, lexleft, &mbs); - if (cur_mb_len <= 0) - { - cur_mb_len = 1; - wc = *lexptr; - } - lexptr += cur_mb_len; - lexleft -= cur_mb_len; - return wc; -} -#else -/* Note that characters become unsigned here. */ -# define FETCH(c, eoferr) \ - { \ - if (! lexleft) \ - { \ - if (eoferr != 0) \ - dfaerror (eoferr); \ - else \ - return lasttok = END; \ - } \ - (c) = (unsigned char) *lexptr++; \ - --lexleft; \ - } -#endif /* MBS_SUPPORT */ - -#ifdef MBS_SUPPORT -/* Multibyte character handling sub-routin for lex. - This function parse a bracket expression and build a struct - mb_char_classes. */ -static void -parse_bracket_exp_mb () -{ - wint_t wc, wc1, wc2; - - /* Work area to build a mb_char_classes. */ - struct mb_char_classes *work_mbc; - int chars_al, range_sts_al, range_ends_al, ch_classes_al, - equivs_al, coll_elems_al; - - REALLOC_IF_NECESSARY(dfa->mbcsets, struct mb_char_classes, - dfa->mbcsets_alloc, dfa->nmbcsets + 1); - /* dfa->multibyte_prop[] hold the index of dfa->mbcsets. - We will update dfa->multibyte_prop in addtok(), because we can't - decide the index in dfa->tokens[]. */ - - /* Initialize work are */ - work_mbc = &(dfa->mbcsets[dfa->nmbcsets++]); - - chars_al = 1; - range_sts_al = range_ends_al = 0; - ch_classes_al = equivs_al = coll_elems_al = 0; - MALLOC(work_mbc->chars, wchar_t, chars_al); - - work_mbc->nchars = work_mbc->nranges = work_mbc->nch_classes = 0; - work_mbc->nequivs = work_mbc->ncoll_elems = 0; - work_mbc->chars = work_mbc->ch_classes = NULL; - work_mbc->range_sts = work_mbc->range_ends = NULL; - work_mbc->equivs = work_mbc->coll_elems = NULL; - - wc = fetch_wc(_("Unbalanced [")); - if (wc == L'^') - { - wc = fetch_wc(_("Unbalanced [")); - work_mbc->invert = 1; - } - else - work_mbc->invert = 0; - do - { - wc1 = WEOF; /* mark wc1 is not initialized". */ - - /* Note that if we're looking at some other [:...:] construct, - we just treat it as a bunch of ordinary characters. We can do - this because we assume regex has checked for syntax errors before - dfa is ever called. */ - if (wc == L'[' && (syntax_bits & RE_CHAR_CLASSES)) - { -#define BRACKET_BUFFER_SIZE 128 - char str[BRACKET_BUFFER_SIZE]; - wc1 = wc; - wc = fetch_wc(_("Unbalanced [")); - - /* If pattern contains `[[:', `[[.', or `[[='. */ - if (cur_mb_len == 1 && (wc == L':' || wc == L'.' || wc == L'=')) - { - unsigned char c; - unsigned char delim = (unsigned char)wc; - int len = 0; - for (;;) - { - if (! lexleft) - dfaerror (_("Unbalanced [")); - c = (unsigned char) *lexptr++; - --lexleft; - - if ((c == delim && *lexptr == ']') || lexleft == 0) - break; - if (len < BRACKET_BUFFER_SIZE) - str[len++] = c; - else - /* This is in any case an invalid class name. */ - str[0] = '\0'; - } - str[len] = '\0'; - - if (lexleft == 0) - { - REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al, - work_mbc->nchars + 2); - work_mbc->chars[work_mbc->nchars++] = L'['; - work_mbc->chars[work_mbc->nchars++] = delim; - break; - } - - if (--lexleft, *lexptr++ != ']') - dfaerror (_("Unbalanced [")); - if (delim == ':') - /* build character class. */ - { - wctype_t wt; - /* Query the character class as wctype_t. */ - wt = wctype (str); - - if (ch_classes_al == 0) - MALLOC(work_mbc->ch_classes, wchar_t, ++ch_classes_al); - REALLOC_IF_NECESSARY(work_mbc->ch_classes, wctype_t, - ch_classes_al, - work_mbc->nch_classes + 1); - work_mbc->ch_classes[work_mbc->nch_classes++] = wt; - - } - else if (delim == '=' || delim == '.') - { - char *elem; - MALLOC(elem, char, len + 1); - strncpy(elem, str, len + 1); - - if (delim == '=') - /* build equivalent class. */ - { - if (equivs_al == 0) - MALLOC(work_mbc->equivs, char*, ++equivs_al); - REALLOC_IF_NECESSARY(work_mbc->equivs, char*, - equivs_al, - work_mbc->nequivs + 1); - work_mbc->equivs[work_mbc->nequivs++] = elem; - } - - if (delim == '.') - /* build collating element. */ - { - if (coll_elems_al == 0) - MALLOC(work_mbc->coll_elems, char*, ++coll_elems_al); - REALLOC_IF_NECESSARY(work_mbc->coll_elems, char*, - coll_elems_al, - work_mbc->ncoll_elems + 1); - work_mbc->coll_elems[work_mbc->ncoll_elems++] = elem; - } - } - wc1 = wc = WEOF; - } - else - /* We treat '[' as a normal character here. */ - { - wc2 = wc1; wc1 = wc; wc = wc2; /* swap */ - } - } - else - { - if (wc == L'\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) - wc = fetch_wc(("Unbalanced [")); - } - - if (wc1 == WEOF) - wc1 = fetch_wc(_("Unbalanced [")); - - if (wc1 == L'-') - /* build range characters. */ - { - wc2 = fetch_wc(_("Unbalanced [")); - if (wc2 == L']') - { - /* In the case [x-], the - is an ordinary hyphen, - which is left in c1, the lookahead character. */ - lexptr -= cur_mb_len; - lexleft += cur_mb_len; - wc2 = wc; - } - else - { - if (wc2 == L'\\' - && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) - wc2 = fetch_wc(_("Unbalanced [")); - wc1 = fetch_wc(_("Unbalanced [")); - } - - if (range_sts_al == 0) - { - MALLOC(work_mbc->range_sts, wchar_t, ++range_sts_al); - MALLOC(work_mbc->range_ends, wchar_t, ++range_ends_al); - } - REALLOC_IF_NECESSARY(work_mbc->range_sts, wchar_t, - range_sts_al, work_mbc->nranges + 1); - work_mbc->range_sts[work_mbc->nranges] = (wchar_t)wc; - REALLOC_IF_NECESSARY(work_mbc->range_ends, wchar_t, - range_ends_al, work_mbc->nranges + 1); - work_mbc->range_ends[work_mbc->nranges++] = (wchar_t)wc2; - } - else if (wc != WEOF) - /* build normal characters. */ - { - REALLOC_IF_NECESSARY(work_mbc->chars, wchar_t, chars_al, - work_mbc->nchars + 1); - work_mbc->chars[work_mbc->nchars++] = (wchar_t)wc; - } - } - while ((wc = wc1) != L']'); -} -#endif /* MBS_SUPPORT */ - -#ifdef __STDC__ -#define FUNC(F, P) static int F(int c) { return P(c); } -#else -#define FUNC(F, P) static int F(c) int c; { return P(c); } -#endif - -FUNC(is_alpha, ISALPHA) -FUNC(is_upper, ISUPPER) -FUNC(is_lower, ISLOWER) -FUNC(is_digit, ISDIGIT) -FUNC(is_xdigit, ISXDIGIT) -FUNC(is_space, ISSPACE) -FUNC(is_punct, ISPUNCT) -FUNC(is_alnum, ISALNUM) -FUNC(is_print, ISPRINT) -FUNC(is_graph, ISGRAPH) -FUNC(is_cntrl, ISCNTRL) - -static int -is_blank (int c) -{ - return (c == ' ' || c == '\t'); -} - -/* The following list maps the names of the Posix named character classes - to predicate functions that determine whether a given character is in - the class. The leading [ has already been eaten by the lexical analyzer. */ -static struct { - const char *name; - int (*pred) PARAMS ((int)); -} const prednames[] = { - { ":alpha:]", is_alpha }, - { ":upper:]", is_upper }, - { ":lower:]", is_lower }, - { ":digit:]", is_digit }, - { ":xdigit:]", is_xdigit }, - { ":space:]", is_space }, - { ":punct:]", is_punct }, - { ":alnum:]", is_alnum }, - { ":print:]", is_print }, - { ":graph:]", is_graph }, - { ":cntrl:]", is_cntrl }, - { ":blank:]", is_blank }, - { 0 } -}; - -/* Return non-zero if C is a `word-constituent' byte; zero otherwise. */ -#define IS_WORD_CONSTITUENT(C) (ISALNUM(C) || (C) == '_') - -static int -looking_at (char const *s) -{ - size_t len; - - len = strlen(s); - if (lexleft < len) - return 0; - return strncmp(s, lexptr, len) == 0; -} - -static token -lex (void) -{ - unsigned c, c1, c2; - int backslash = 0, invert; - charclass ccl; - int i; - - /* Basic plan: We fetch a character. If it's a backslash, - we set the backslash flag and go through the loop again. - On the plus side, this avoids having a duplicate of the - main switch inside the backslash case. On the minus side, - it means that just about every case begins with - "if (backslash) ...". */ - for (i = 0; i < 2; ++i) - { - FETCH(c, 0); -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1 && cur_mb_index) - /* If this is a part of a multi-byte character, we must treat - this byte data as a normal character. - e.g. In case of SJIS encoding, some character contains '\', - but they must not be backslash. */ - goto normal_char; -#endif /* MBS_SUPPORT */ - switch (c) - { - case '\\': - if (backslash) - goto normal_char; - if (lexleft == 0) - dfaerror(_("Unfinished \\ escape")); - backslash = 1; - break; - - case '^': - if (backslash) - goto normal_char; - if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS - || lasttok == END - || lasttok == LPAREN - || lasttok == OR) - return lasttok = BEGLINE; - goto normal_char; - - case '$': - if (backslash) - goto normal_char; - if (syntax_bits & RE_CONTEXT_INDEP_ANCHORS - || lexleft == 0 - || (syntax_bits & RE_NO_BK_PARENS - ? lexleft > 0 && *lexptr == ')' - : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == ')') - || (syntax_bits & RE_NO_BK_VBAR - ? lexleft > 0 && *lexptr == '|' - : lexleft > 1 && lexptr[0] == '\\' && lexptr[1] == '|') - || ((syntax_bits & RE_NEWLINE_ALT) - && lexleft > 0 && *lexptr == '\n')) - return lasttok = ENDLINE; - goto normal_char; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (backslash && !(syntax_bits & RE_NO_BK_REFS)) - { - laststart = 0; - return lasttok = BACKREF; - } - goto normal_char; - - case '`': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = BEGLINE; /* FIXME: should be beginning of string */ - goto normal_char; - - case '\'': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = ENDLINE; /* FIXME: should be end of string */ - goto normal_char; - - case '<': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = BEGWORD; - goto normal_char; - - case '>': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = ENDWORD; - goto normal_char; - - case 'b': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = LIMWORD; - goto normal_char; - - case 'B': - if (backslash && !(syntax_bits & RE_NO_GNU_OPS)) - return lasttok = NOTLIMWORD; - goto normal_char; - - case '?': - if (syntax_bits & RE_LIMITED_OPS) - goto normal_char; - if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0)) - goto normal_char; - if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) - goto normal_char; - return lasttok = QMARK; - - case '*': - if (backslash) - goto normal_char; - if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) - goto normal_char; - return lasttok = STAR; - - case '+': - if (syntax_bits & RE_LIMITED_OPS) - goto normal_char; - if (backslash != ((syntax_bits & RE_BK_PLUS_QM) != 0)) - goto normal_char; - if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) - goto normal_char; - return lasttok = PLUS; - - case '{': - if (!(syntax_bits & RE_INTERVALS)) - goto normal_char; - if (backslash != ((syntax_bits & RE_NO_BK_BRACES) == 0)) - goto normal_char; - if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart) - goto normal_char; - - if (syntax_bits & RE_NO_BK_BRACES) - { - /* Scan ahead for a valid interval; if it's not valid, - treat it as a literal '{'. */ - int lo = -1, hi = -1; - char const *p = lexptr; - char const *lim = p + lexleft; - for (; p != lim && ISASCIIDIGIT (*p); p++) - lo = (lo < 0 ? 0 : lo * 10) + *p - '0'; - if (p != lim && *p == ',') - while (++p != lim && ISASCIIDIGIT (*p)) - hi = (hi < 0 ? 0 : hi * 10) + *p - '0'; - else - hi = lo; - if (p == lim || *p != '}' - || lo < 0 || RE_DUP_MAX < hi || (0 <= hi && hi < lo)) - goto normal_char; - } - - minrep = 0; - /* Cases: - {M} - exact count - {M,} - minimum count, maximum is infinity - {M,N} - M through N */ - FETCH(c, _("unfinished repeat count")); - if (ISASCIIDIGIT (c)) - { - minrep = c - '0'; - for (;;) - { - FETCH(c, _("unfinished repeat count")); - if (! ISASCIIDIGIT (c)) - break; - minrep = 10 * minrep + c - '0'; - } - } - else - dfaerror(_("malformed repeat count")); - if (c == ',') - { - FETCH (c, _("unfinished repeat count")); - if (! ISASCIIDIGIT (c)) - maxrep = -1; - else - { - maxrep = c - '0'; - for (;;) - { - FETCH (c, _("unfinished repeat count")); - if (! ISASCIIDIGIT (c)) - break; - maxrep = 10 * maxrep + c - '0'; - } - if (0 <= maxrep && maxrep < minrep) - dfaerror (_("malformed repeat count")); - } - } - else - maxrep = minrep; - if (!(syntax_bits & RE_NO_BK_BRACES)) - { - if (c != '\\') - dfaerror(_("malformed repeat count")); - FETCH(c, _("unfinished repeat count")); - } - if (c != '}') - dfaerror(_("malformed repeat count")); - laststart = 0; - return lasttok = REPMN; - - case '|': - if (syntax_bits & RE_LIMITED_OPS) - goto normal_char; - if (backslash != ((syntax_bits & RE_NO_BK_VBAR) == 0)) - goto normal_char; - laststart = 1; - return lasttok = OR; - - case '\n': - if (syntax_bits & RE_LIMITED_OPS - || backslash - || !(syntax_bits & RE_NEWLINE_ALT)) - goto normal_char; - laststart = 1; - return lasttok = OR; - - case '(': - if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0)) - goto normal_char; - ++parens; - laststart = 1; - return lasttok = LPAREN; - - case ')': - if (backslash != ((syntax_bits & RE_NO_BK_PARENS) == 0)) - goto normal_char; - if (parens == 0 && syntax_bits & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_char; - --parens; - laststart = 0; - return lasttok = RPAREN; - - case '.': - if (backslash) - goto normal_char; -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - /* In multibyte environment period must match with a single - character not a byte. So we use ANYCHAR. */ - laststart = 0; - return lasttok = ANYCHAR; - } -#endif /* MBS_SUPPORT */ - zeroset(ccl); - notset(ccl); - if (!(syntax_bits & RE_DOT_NEWLINE)) - clrbit(eolbyte, ccl); - if (syntax_bits & RE_DOT_NOT_NULL) - clrbit('\0', ccl); - laststart = 0; - return lasttok = CSET + charclass_index(ccl); - - case 'w': - case 'W': - if (!backslash || (syntax_bits & RE_NO_GNU_OPS)) - goto normal_char; - zeroset(ccl); - for (c2 = 0; c2 < NOTCHAR; ++c2) - if (IS_WORD_CONSTITUENT(c2)) - setbit(c2, ccl); - if (c == 'W') - notset(ccl); - laststart = 0; - return lasttok = CSET + charclass_index(ccl); - - case '[': - if (backslash) - goto normal_char; - laststart = 0; -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - /* In multibyte environment a bracket expression may contain - multibyte characters, which must be treated as characters - (not bytes). So we parse it by parse_bracket_exp_mb(). */ - parse_bracket_exp_mb(); - return lasttok = MBCSET; - } -#endif - zeroset(ccl); - FETCH(c, _("Unbalanced [")); - if (c == '^') - { - FETCH(c, _("Unbalanced [")); - invert = 1; - } - else - invert = 0; - do - { - /* Nobody ever said this had to be fast. :-) - Note that if we're looking at some other [:...:] - construct, we just treat it as a bunch of ordinary - characters. We can do this because we assume - regex has checked for syntax errors before - dfa is ever called. */ - if (c == '[' && (syntax_bits & RE_CHAR_CLASSES)) - for (c1 = 0; prednames[c1].name; ++c1) - if (looking_at(prednames[c1].name)) - { - int (*pred) PARAMS ((int)) = prednames[c1].pred; - - for (c2 = 0; c2 < NOTCHAR; ++c2) - if ((*pred)(c2)) - setbit_case_fold (c2, ccl); - lexptr += strlen(prednames[c1].name); - lexleft -= strlen(prednames[c1].name); - FETCH(c1, _("Unbalanced [")); - goto skip; - } - if (c == '\\' && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) - FETCH(c, _("Unbalanced [")); - FETCH(c1, _("Unbalanced [")); - if (c1 == '-') - { - FETCH(c2, _("Unbalanced [")); - if (c2 == ']') - { - /* In the case [x-], the - is an ordinary hyphen, - which is left in c1, the lookahead character. */ - --lexptr; - ++lexleft; - } - else - { - if (c2 == '\\' - && (syntax_bits & RE_BACKSLASH_ESCAPE_IN_LISTS)) - FETCH(c2, _("Unbalanced [")); - FETCH(c1, _("Unbalanced [")); - if (!hard_LC_COLLATE) { - for (; c <= c2; c++) - setbit_case_fold (c, ccl); - } else { - /* POSIX locales are painful - leave the decision to libc */ - char expr[6] = { '[', c, '-', c2, ']', '\0' }; - regex_t re; - if (regcomp (&re, expr, case_fold ? REG_ICASE : 0) == REG_NOERROR) { - for (c = 0; c < NOTCHAR; ++c) { - char buf[2] = { c, '\0' }; - regmatch_t mat; - if (regexec (&re, buf, 1, &mat, 0) == REG_NOERROR - && mat.rm_so == 0 && mat.rm_eo == 1) - setbit_case_fold (c, ccl); - } - regfree (&re); - } - } - continue; - } - } - - setbit_case_fold (c, ccl); - - skip: - ; - } - while ((c = c1) != ']'); - if (invert) - { - notset(ccl); - if (syntax_bits & RE_HAT_LISTS_NOT_NEWLINE) - clrbit(eolbyte, ccl); - } - return lasttok = CSET + charclass_index(ccl); - - default: - normal_char: - laststart = 0; - if (case_fold && ISALPHA(c)) - { - zeroset(ccl); - setbit_case_fold (c, ccl); - return lasttok = CSET + charclass_index(ccl); - } - return c; - } - } - - /* The above loop should consume at most a backslash - and some other character. */ - abort(); - return END; /* keeps pedantic compilers happy. */ -} - -/* Recursive descent parser for regular expressions. */ - -static token tok; /* Lookahead token. */ -static int depth; /* Current depth of a hypothetical stack - holding deferred productions. This is - used to determine the depth that will be - required of the real stack later on in - dfaanalyze(). */ - -/* Add the given token to the parse tree, maintaining the depth count and - updating the maximum depth if necessary. */ -static void -addtok (token t) -{ -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - REALLOC_IF_NECESSARY(dfa->multibyte_prop, int, dfa->nmultibyte_prop, - dfa->tindex); - /* Set dfa->multibyte_prop. See struct dfa in dfa.h. */ - if (t == MBCSET) - dfa->multibyte_prop[dfa->tindex] = ((dfa->nmbcsets - 1) << 2) + 3; - else if (t < NOTCHAR) - dfa->multibyte_prop[dfa->tindex] - = (cur_mb_len == 1)? 3 /* single-byte char */ - : (((cur_mb_index == 1)? 1 : 0) /* 1st-byte of multibyte char */ - + ((cur_mb_index == cur_mb_len)? 2 : 0)); /* last-byte */ - else - /* It may be unnecesssary, but it is safer to treat other - symbols as singlebyte characters. */ - dfa->multibyte_prop[dfa->tindex] = 3; - } -#endif - - REALLOC_IF_NECESSARY(dfa->tokens, token, dfa->talloc, dfa->tindex); - dfa->tokens[dfa->tindex++] = t; - - switch (t) - { - case QMARK: - case STAR: - case PLUS: - break; - - case CAT: - case OR: - case ORTOP: - --depth; - break; - - default: - ++dfa->nleaves; - case EMPTY: - ++depth; - break; - } - if (depth > dfa->depth) - dfa->depth = depth; -} - -/* The grammar understood by the parser is as follows. - - regexp: - regexp OR branch - branch - - branch: - branch closure - closure - - closure: - closure QMARK - closure STAR - closure PLUS - closure REPMN - atom - - atom: - - - ANYCHAR - MBCSET - CSET - BACKREF - BEGLINE - ENDLINE - BEGWORD - ENDWORD - LIMWORD - NOTLIMWORD - CRANGE - LPAREN regexp RPAREN - - - The parser builds a parse tree in postfix form in an array of tokens. */ - -static void -atom (void) -{ - if ((tok >= 0 && tok < NOTCHAR) || tok >= CSET || tok == BACKREF - || tok == BEGLINE || tok == ENDLINE || tok == BEGWORD -#ifdef MBS_SUPPORT - || tok == ANYCHAR || tok == MBCSET /* MB_CUR_MAX > 1 */ -#endif /* MBS_SUPPORT */ - || tok == ENDWORD || tok == LIMWORD || tok == NOTLIMWORD) - { - addtok(tok); - tok = lex(); -#ifdef MBS_SUPPORT - /* We treat a multibyte character as a single atom, so that DFA - can treat a multibyte character as a single expression. - - e.g. We construct following tree from "". - - - */ - if (MB_CUR_MAX > 1) - { - while (cur_mb_index > 1 && tok >= 0 && tok < NOTCHAR) - { - addtok(tok); - addtok(CAT); - tok = lex(); - } - } -#endif /* MBS_SUPPORT */ - } - else if (tok == CRANGE) - { - /* A character range like "[a-z]" in a locale other than "C" or - "POSIX". This range might any sequence of one or more - characters. Unfortunately the POSIX locale primitives give - us no practical way to find what character sequences might be - matched. Treat this approximately like "(.\1)" -- i.e. match - one character, and then punt to the full matcher. */ - charclass ccl; - zeroset (ccl); - notset (ccl); - addtok (CSET + charclass_index (ccl)); - addtok (BACKREF); - addtok (CAT); - tok = lex (); - } - else if (tok == LPAREN) - { - tok = lex(); - regexp(0); - if (tok != RPAREN) - dfaerror(_("Unbalanced (")); - tok = lex(); - } - else - addtok(EMPTY); -} - -/* Return the number of tokens in the given subexpression. */ -static int -nsubtoks (int tindex) -{ - int ntoks1; - - switch (dfa->tokens[tindex - 1]) - { - default: - return 1; - case QMARK: - case STAR: - case PLUS: - return 1 + nsubtoks(tindex - 1); - case CAT: - case OR: - case ORTOP: - ntoks1 = nsubtoks(tindex - 1); - return 1 + ntoks1 + nsubtoks(tindex - 1 - ntoks1); - } -} - -/* Copy the given subexpression to the top of the tree. */ -static void -copytoks (int tindex, int ntokens) -{ - int i; - - for (i = 0; i < ntokens; ++i) - addtok(dfa->tokens[tindex + i]); -} - -static void -closure (void) -{ - int tindex, ntokens, i; - - atom(); - while (tok == QMARK || tok == STAR || tok == PLUS || tok == REPMN) - if (tok == REPMN) - { - ntokens = nsubtoks(dfa->tindex); - tindex = dfa->tindex - ntokens; - if (maxrep < 0) - addtok(PLUS); - if (minrep == 0) - addtok(QMARK); - for (i = 1; i < minrep; ++i) - { - copytoks(tindex, ntokens); - addtok(CAT); - } - for (; i < maxrep; ++i) - { - copytoks(tindex, ntokens); - addtok(QMARK); - addtok(CAT); - } - tok = lex(); - } - else - { - addtok(tok); - tok = lex(); - } -} - -static void -branch (void) -{ - closure(); - while (tok != RPAREN && tok != OR && tok >= 0) - { - closure(); - addtok(CAT); - } -} - -static void -regexp (int toplevel) -{ - branch(); - while (tok == OR) - { - tok = lex(); - branch(); - if (toplevel) - addtok(ORTOP); - else - addtok(OR); - } -} - -/* Main entry point for the parser. S is a string to be parsed, len is the - length of the string, so s can include NUL characters. D is a pointer to - the struct dfa to parse into. */ -void -dfaparse (char const *s, size_t len, struct dfa *d) -{ - dfa = d; - lexstart = lexptr = s; - lexleft = len; - lasttok = END; - laststart = 1; - parens = 0; - hard_LC_COLLATE = hard_locale (LC_COLLATE); -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - cur_mb_index = 0; - cur_mb_len = 0; - memset(&mbs, 0, sizeof(mbstate_t)); - } -#endif /* MBS_SUPPORT */ - - if (! syntax_bits_set) - dfaerror(_("No syntax specified")); - - tok = lex(); - depth = d->depth; - - regexp(1); - - if (tok != END) - dfaerror(_("Unbalanced )")); - - addtok(END - d->nregexps); - addtok(CAT); - - if (d->nregexps) - addtok(ORTOP); - - ++d->nregexps; -} - -/* Some primitives for operating on sets of positions. */ - -/* Copy one set to another; the destination must be large enough. */ -static void -copy (position_set const *src, position_set *dst) -{ - int i; - - for (i = 0; i < src->nelem; ++i) - dst->elems[i] = src->elems[i]; - dst->nelem = src->nelem; -} - -/* Insert a position in a set. Position sets are maintained in sorted - order according to index. If position already exists in the set with - the same index then their constraints are logically or'd together. - S->elems must point to an array large enough to hold the resulting set. */ -static void -insert (position p, position_set *s) -{ - int i; - position t1, t2; - - for (i = 0; i < s->nelem && p.index < s->elems[i].index; ++i) - continue; - if (i < s->nelem && p.index == s->elems[i].index) - s->elems[i].constraint |= p.constraint; - else - { - t1 = p; - ++s->nelem; - while (i < s->nelem) - { - t2 = s->elems[i]; - s->elems[i++] = t1; - t1 = t2; - } - } -} - -/* Merge two sets of positions into a third. The result is exactly as if - the positions of both sets were inserted into an initially empty set. */ -static void -merge (position_set const *s1, position_set const *s2, position_set *m) -{ - int i = 0, j = 0; - - m->nelem = 0; - while (i < s1->nelem && j < s2->nelem) - if (s1->elems[i].index > s2->elems[j].index) - m->elems[m->nelem++] = s1->elems[i++]; - else if (s1->elems[i].index < s2->elems[j].index) - m->elems[m->nelem++] = s2->elems[j++]; - else - { - m->elems[m->nelem] = s1->elems[i++]; - m->elems[m->nelem++].constraint |= s2->elems[j++].constraint; - } - while (i < s1->nelem) - m->elems[m->nelem++] = s1->elems[i++]; - while (j < s2->nelem) - m->elems[m->nelem++] = s2->elems[j++]; -} - -/* Delete a position from a set. */ -static void -delete (position p, position_set *s) -{ - int i; - - for (i = 0; i < s->nelem; ++i) - if (p.index == s->elems[i].index) - break; - if (i < s->nelem) - for (--s->nelem; i < s->nelem; ++i) - s->elems[i] = s->elems[i + 1]; -} - -/* Find the index of the state corresponding to the given position set with - the given preceding context, or create a new state if there is no such - state. Newline and letter tell whether we got here on a newline or - letter, respectively. */ -static int -state_index (struct dfa *d, position_set const *s, int newline, int letter) -{ - int hash = 0; - int constraint; - int i, j; - - newline = newline ? 1 : 0; - letter = letter ? 1 : 0; - - for (i = 0; i < s->nelem; ++i) - hash ^= s->elems[i].index + s->elems[i].constraint; - - /* Try to find a state that exactly matches the proposed one. */ - for (i = 0; i < d->sindex; ++i) - { - if (hash != d->states[i].hash || s->nelem != d->states[i].elems.nelem - || newline != d->states[i].newline || letter != d->states[i].letter) - continue; - for (j = 0; j < s->nelem; ++j) - if (s->elems[j].constraint - != d->states[i].elems.elems[j].constraint - || s->elems[j].index != d->states[i].elems.elems[j].index) - break; - if (j == s->nelem) - return i; - } - - /* We'll have to create a new state. */ - REALLOC_IF_NECESSARY(d->states, dfa_state, d->salloc, d->sindex); - d->states[i].hash = hash; - MALLOC(d->states[i].elems.elems, position, s->nelem); - copy(s, &d->states[i].elems); - d->states[i].newline = newline; - d->states[i].letter = letter; - d->states[i].backref = 0; - d->states[i].constraint = 0; - d->states[i].first_end = 0; -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - d->states[i].mbps.nelem = 0; -#endif - for (j = 0; j < s->nelem; ++j) - if (d->tokens[s->elems[j].index] < 0) - { - constraint = s->elems[j].constraint; - if (SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 0) - || SUCCEEDS_IN_CONTEXT(constraint, newline, 0, letter, 1) - || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 0) - || SUCCEEDS_IN_CONTEXT(constraint, newline, 1, letter, 1)) - d->states[i].constraint |= constraint; - if (! d->states[i].first_end) - d->states[i].first_end = d->tokens[s->elems[j].index]; - } - else if (d->tokens[s->elems[j].index] == BACKREF) - { - d->states[i].constraint = NO_CONSTRAINT; - d->states[i].backref = 1; - } - - ++d->sindex; - - return i; -} - -/* Find the epsilon closure of a set of positions. If any position of the set - contains a symbol that matches the empty string in some context, replace - that position with the elements of its follow labeled with an appropriate - constraint. Repeat exhaustively until no funny positions are left. - S->elems must be large enough to hold the result. */ -static void -epsclosure (position_set *s, struct dfa const *d) -{ - int i, j; - int *visited; - position p, old; - - MALLOC(visited, int, d->tindex); - for (i = 0; i < d->tindex; ++i) - visited[i] = 0; - - for (i = 0; i < s->nelem; ++i) - if (d->tokens[s->elems[i].index] >= NOTCHAR - && d->tokens[s->elems[i].index] != BACKREF -#ifdef MBS_SUPPORT - && d->tokens[s->elems[i].index] != ANYCHAR - && d->tokens[s->elems[i].index] != MBCSET -#endif - && d->tokens[s->elems[i].index] < CSET) - { - old = s->elems[i]; - p.constraint = old.constraint; - delete(s->elems[i], s); - if (visited[old.index]) - { - --i; - continue; - } - visited[old.index] = 1; - switch (d->tokens[old.index]) - { - case BEGLINE: - p.constraint &= BEGLINE_CONSTRAINT; - break; - case ENDLINE: - p.constraint &= ENDLINE_CONSTRAINT; - break; - case BEGWORD: - p.constraint &= BEGWORD_CONSTRAINT; - break; - case ENDWORD: - p.constraint &= ENDWORD_CONSTRAINT; - break; - case LIMWORD: - p.constraint &= LIMWORD_CONSTRAINT; - break; - case NOTLIMWORD: - p.constraint &= NOTLIMWORD_CONSTRAINT; - break; - default: - break; - } - for (j = 0; j < d->follows[old.index].nelem; ++j) - { - p.index = d->follows[old.index].elems[j].index; - insert(p, s); - } - /* Force rescan to start at the beginning. */ - i = -1; - } - - free(visited); -} - -/* Perform bottom-up analysis on the parse tree, computing various functions. - Note that at this point, we're pretending constructs like \< are real - characters rather than constraints on what can follow them. - - Nullable: A node is nullable if it is at the root of a regexp that can - match the empty string. - * EMPTY leaves are nullable. - * No other leaf is nullable. - * A QMARK or STAR node is nullable. - * A PLUS node is nullable if its argument is nullable. - * A CAT node is nullable if both its arguments are nullable. - * An OR node is nullable if either argument is nullable. - - Firstpos: The firstpos of a node is the set of positions (nonempty leaves) - that could correspond to the first character of a string matching the - regexp rooted at the given node. - * EMPTY leaves have empty firstpos. - * The firstpos of a nonempty leaf is that leaf itself. - * The firstpos of a QMARK, STAR, or PLUS node is the firstpos of its - argument. - * The firstpos of a CAT node is the firstpos of the left argument, union - the firstpos of the right if the left argument is nullable. - * The firstpos of an OR node is the union of firstpos of each argument. - - Lastpos: The lastpos of a node is the set of positions that could - correspond to the last character of a string matching the regexp at - the given node. - * EMPTY leaves have empty lastpos. - * The lastpos of a nonempty leaf is that leaf itself. - * The lastpos of a QMARK, STAR, or PLUS node is the lastpos of its - argument. - * The lastpos of a CAT node is the lastpos of its right argument, union - the lastpos of the left if the right argument is nullable. - * The lastpos of an OR node is the union of the lastpos of each argument. - - Follow: The follow of a position is the set of positions that could - correspond to the character following a character matching the node in - a string matching the regexp. At this point we consider special symbols - that match the empty string in some context to be just normal characters. - Later, if we find that a special symbol is in a follow set, we will - replace it with the elements of its follow, labeled with an appropriate - constraint. - * Every node in the firstpos of the argument of a STAR or PLUS node is in - the follow of every node in the lastpos. - * Every node in the firstpos of the second argument of a CAT node is in - the follow of every node in the lastpos of the first argument. - - Because of the postfix representation of the parse tree, the depth-first - analysis is conveniently done by a linear scan with the aid of a stack. - Sets are stored as arrays of the elements, obeying a stack-like allocation - scheme; the number of elements in each set deeper in the stack can be - used to determine the address of a particular set's array. */ -void -dfaanalyze (struct dfa *d, int searchflag) -{ - int *nullable; /* Nullable stack. */ - int *nfirstpos; /* Element count stack for firstpos sets. */ - position *firstpos; /* Array where firstpos elements are stored. */ - int *nlastpos; /* Element count stack for lastpos sets. */ - position *lastpos; /* Array where lastpos elements are stored. */ - int *nalloc; /* Sizes of arrays allocated to follow sets. */ - position_set tmp; /* Temporary set for merging sets. */ - position_set merged; /* Result of merging sets. */ - int wants_newline; /* True if some position wants newline info. */ - int *o_nullable; - int *o_nfirst, *o_nlast; - position *o_firstpos, *o_lastpos; - int i, j; - position *pos; - -#ifdef DEBUG - fprintf(stderr, "dfaanalyze:\n"); - for (i = 0; i < d->tindex; ++i) - { - fprintf(stderr, " %d:", i); - prtok(d->tokens[i]); - } - putc('\n', stderr); -#endif - - d->searchflag = searchflag; - - MALLOC(nullable, int, d->depth); - o_nullable = nullable; - MALLOC(nfirstpos, int, d->depth); - o_nfirst = nfirstpos; - MALLOC(firstpos, position, d->nleaves); - o_firstpos = firstpos, firstpos += d->nleaves; - MALLOC(nlastpos, int, d->depth); - o_nlast = nlastpos; - MALLOC(lastpos, position, d->nleaves); - o_lastpos = lastpos, lastpos += d->nleaves; - MALLOC(nalloc, int, d->tindex); - for (i = 0; i < d->tindex; ++i) - nalloc[i] = 0; - MALLOC(merged.elems, position, d->nleaves); - - CALLOC(d->follows, position_set, d->tindex); - - for (i = 0; i < d->tindex; ++i) -#ifdef DEBUG - { /* Nonsyntactic #ifdef goo... */ -#endif - switch (d->tokens[i]) - { - case EMPTY: - /* The empty set is nullable. */ - *nullable++ = 1; - - /* The firstpos and lastpos of the empty leaf are both empty. */ - *nfirstpos++ = *nlastpos++ = 0; - break; - - case STAR: - case PLUS: - /* Every element in the firstpos of the argument is in the follow - of every element in the lastpos. */ - tmp.nelem = nfirstpos[-1]; - tmp.elems = firstpos; - pos = lastpos; - for (j = 0; j < nlastpos[-1]; ++j) - { - merge(&tmp, &d->follows[pos[j].index], &merged); - REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position, - nalloc[pos[j].index], merged.nelem - 1); - copy(&merged, &d->follows[pos[j].index]); - } - - case QMARK: - /* A QMARK or STAR node is automatically nullable. */ - if (d->tokens[i] != PLUS) - nullable[-1] = 1; - break; - - case CAT: - /* Every element in the firstpos of the second argument is in the - follow of every element in the lastpos of the first argument. */ - tmp.nelem = nfirstpos[-1]; - tmp.elems = firstpos; - pos = lastpos + nlastpos[-1]; - for (j = 0; j < nlastpos[-2]; ++j) - { - merge(&tmp, &d->follows[pos[j].index], &merged); - REALLOC_IF_NECESSARY(d->follows[pos[j].index].elems, position, - nalloc[pos[j].index], merged.nelem - 1); - copy(&merged, &d->follows[pos[j].index]); - } - - /* The firstpos of a CAT node is the firstpos of the first argument, - union that of the second argument if the first is nullable. */ - if (nullable[-2]) - nfirstpos[-2] += nfirstpos[-1]; - else - firstpos += nfirstpos[-1]; - --nfirstpos; - - /* The lastpos of a CAT node is the lastpos of the second argument, - union that of the first argument if the second is nullable. */ - if (nullable[-1]) - nlastpos[-2] += nlastpos[-1]; - else - { - pos = lastpos + nlastpos[-2]; - for (j = nlastpos[-1] - 1; j >= 0; --j) - pos[j] = lastpos[j]; - lastpos += nlastpos[-2]; - nlastpos[-2] = nlastpos[-1]; - } - --nlastpos; - - /* A CAT node is nullable if both arguments are nullable. */ - nullable[-2] = nullable[-1] && nullable[-2]; - --nullable; - break; - - case OR: - case ORTOP: - /* The firstpos is the union of the firstpos of each argument. */ - nfirstpos[-2] += nfirstpos[-1]; - --nfirstpos; - - /* The lastpos is the union of the lastpos of each argument. */ - nlastpos[-2] += nlastpos[-1]; - --nlastpos; - - /* An OR node is nullable if either argument is nullable. */ - nullable[-2] = nullable[-1] || nullable[-2]; - --nullable; - break; - - default: - /* Anything else is a nonempty position. (Note that special - constructs like \< are treated as nonempty strings here; - an "epsilon closure" effectively makes them nullable later. - Backreferences have to get a real position so we can detect - transitions on them later. But they are nullable. */ - *nullable++ = d->tokens[i] == BACKREF; - - /* This position is in its own firstpos and lastpos. */ - *nfirstpos++ = *nlastpos++ = 1; - --firstpos, --lastpos; - firstpos->index = lastpos->index = i; - firstpos->constraint = lastpos->constraint = NO_CONSTRAINT; - - /* Allocate the follow set for this position. */ - nalloc[i] = 1; - MALLOC(d->follows[i].elems, position, nalloc[i]); - break; - } -#ifdef DEBUG - /* ... balance the above nonsyntactic #ifdef goo... */ - fprintf(stderr, "node %d:", i); - prtok(d->tokens[i]); - putc('\n', stderr); - fprintf(stderr, nullable[-1] ? " nullable: yes\n" : " nullable: no\n"); - fprintf(stderr, " firstpos:"); - for (j = nfirstpos[-1] - 1; j >= 0; --j) - { - fprintf(stderr, " %d:", firstpos[j].index); - prtok(d->tokens[firstpos[j].index]); - } - fprintf(stderr, "\n lastpos:"); - for (j = nlastpos[-1] - 1; j >= 0; --j) - { - fprintf(stderr, " %d:", lastpos[j].index); - prtok(d->tokens[lastpos[j].index]); - } - putc('\n', stderr); - } -#endif - - /* For each follow set that is the follow set of a real position, replace - it with its epsilon closure. */ - for (i = 0; i < d->tindex; ++i) - if (d->tokens[i] < NOTCHAR || d->tokens[i] == BACKREF -#ifdef MBS_SUPPORT - || d->tokens[i] == ANYCHAR - || d->tokens[i] == MBCSET -#endif - || d->tokens[i] >= CSET) - { -#ifdef DEBUG - fprintf(stderr, "follows(%d:", i); - prtok(d->tokens[i]); - fprintf(stderr, "):"); - for (j = d->follows[i].nelem - 1; j >= 0; --j) - { - fprintf(stderr, " %d:", d->follows[i].elems[j].index); - prtok(d->tokens[d->follows[i].elems[j].index]); - } - putc('\n', stderr); -#endif - copy(&d->follows[i], &merged); - epsclosure(&merged, d); - if (d->follows[i].nelem < merged.nelem) - REALLOC(d->follows[i].elems, position, merged.nelem); - copy(&merged, &d->follows[i]); - } - - /* Get the epsilon closure of the firstpos of the regexp. The result will - be the set of positions of state 0. */ - merged.nelem = 0; - for (i = 0; i < nfirstpos[-1]; ++i) - insert(firstpos[i], &merged); - epsclosure(&merged, d); - - /* Check if any of the positions of state 0 will want newline context. */ - wants_newline = 0; - for (i = 0; i < merged.nelem; ++i) - if (PREV_NEWLINE_DEPENDENT(merged.elems[i].constraint)) - wants_newline = 1; - - /* Build the initial state. */ - d->salloc = 1; - d->sindex = 0; - MALLOC(d->states, dfa_state, d->salloc); - state_index(d, &merged, wants_newline, 0); - - free(o_nullable); - free(o_nfirst); - free(o_firstpos); - free(o_nlast); - free(o_lastpos); - free(nalloc); - free(merged.elems); -} - -/* Find, for each character, the transition out of state s of d, and store - it in the appropriate slot of trans. - - We divide the positions of s into groups (positions can appear in more - than one group). Each group is labeled with a set of characters that - every position in the group matches (taking into account, if necessary, - preceding context information of s). For each group, find the union - of the its elements' follows. This set is the set of positions of the - new state. For each character in the group's label, set the transition - on this character to be to a state corresponding to the set's positions, - and its associated backward context information, if necessary. - - If we are building a searching matcher, we include the positions of state - 0 in every state. - - The collection of groups is constructed by building an equivalence-class - partition of the positions of s. - - For each position, find the set of characters C that it matches. Eliminate - any characters from C that fail on grounds of backward context. - - Search through the groups, looking for a group whose label L has nonempty - intersection with C. If L - C is nonempty, create a new group labeled - L - C and having the same positions as the current group, and set L to - the intersection of L and C. Insert the position in this group, set - C = C - L, and resume scanning. - - If after comparing with every group there are characters remaining in C, - create a new group labeled with the characters of C and insert this - position in that group. */ -void -dfastate (int s, struct dfa *d, int trans[]) -{ - position_set grps[NOTCHAR]; /* As many as will ever be needed. */ - charclass labels[NOTCHAR]; /* Labels corresponding to the groups. */ - int ngrps = 0; /* Number of groups actually used. */ - position pos; /* Current position being considered. */ - charclass matches; /* Set of matching characters. */ - int matchesf; /* True if matches is nonempty. */ - charclass intersect; /* Intersection with some label set. */ - int intersectf; /* True if intersect is nonempty. */ - charclass leftovers; /* Stuff in the label that didn't match. */ - int leftoversf; /* True if leftovers is nonempty. */ - static charclass letters; /* Set of characters considered letters. */ - static charclass newline; /* Set of characters that aren't newline. */ - position_set follows; /* Union of the follows of some group. */ - position_set tmp; /* Temporary space for merging sets. */ - int state; /* New state. */ - int wants_newline; /* New state wants to know newline context. */ - int state_newline; /* New state on a newline transition. */ - int wants_letter; /* New state wants to know letter context. */ - int state_letter; /* New state on a letter transition. */ - static int initialized; /* Flag for static initialization. */ -#ifdef MBS_SUPPORT - int next_isnt_1st_byte = 0; /* Flag If we can't add state0. */ -#endif - int i, j, k; - - /* Initialize the set of letters, if necessary. */ - if (! initialized) - { - initialized = 1; - for (i = 0; i < NOTCHAR; ++i) - if (IS_WORD_CONSTITUENT(i)) - setbit(i, letters); - setbit(eolbyte, newline); - } - - zeroset(matches); - - for (i = 0; i < d->states[s].elems.nelem; ++i) - { - pos = d->states[s].elems.elems[i]; - if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR) - setbit(d->tokens[pos.index], matches); - else if (d->tokens[pos.index] >= CSET) - copyset(d->charclasses[d->tokens[pos.index] - CSET], matches); -#ifdef MBS_SUPPORT - else if (d->tokens[pos.index] == ANYCHAR - || d->tokens[pos.index] == MBCSET) - /* MB_CUR_MAX > 1 */ - { - /* ANYCHAR and MBCSET must match with a single character, so we - must put it to d->states[s].mbps, which contains the positions - which can match with a single character not a byte. */ - if (d->states[s].mbps.nelem == 0) - { - MALLOC(d->states[s].mbps.elems, position, - d->states[s].elems.nelem); - } - insert(pos, &(d->states[s].mbps)); - continue; - } -#endif /* MBS_SUPPORT */ - else - continue; - - /* Some characters may need to be eliminated from matches because - they fail in the current context. */ - if (pos.constraint != 0xFF) - { - if (! MATCHES_NEWLINE_CONTEXT(pos.constraint, - d->states[s].newline, 1)) - clrbit(eolbyte, matches); - if (! MATCHES_NEWLINE_CONTEXT(pos.constraint, - d->states[s].newline, 0)) - for (j = 0; j < CHARCLASS_INTS; ++j) - matches[j] &= newline[j]; - if (! MATCHES_LETTER_CONTEXT(pos.constraint, - d->states[s].letter, 1)) - for (j = 0; j < CHARCLASS_INTS; ++j) - matches[j] &= ~letters[j]; - if (! MATCHES_LETTER_CONTEXT(pos.constraint, - d->states[s].letter, 0)) - for (j = 0; j < CHARCLASS_INTS; ++j) - matches[j] &= letters[j]; - - /* If there are no characters left, there's no point in going on. */ - for (j = 0; j < CHARCLASS_INTS && !matches[j]; ++j) - continue; - if (j == CHARCLASS_INTS) - continue; - } - - for (j = 0; j < ngrps; ++j) - { - /* If matches contains a single character only, and the current - group's label doesn't contain that character, go on to the - next group. */ - if (d->tokens[pos.index] >= 0 && d->tokens[pos.index] < NOTCHAR - && !tstbit(d->tokens[pos.index], labels[j])) - continue; - - /* Check if this group's label has a nonempty intersection with - matches. */ - intersectf = 0; - for (k = 0; k < CHARCLASS_INTS; ++k) - (intersect[k] = matches[k] & labels[j][k]) ? (intersectf = 1) : 0; - if (! intersectf) - continue; - - /* It does; now find the set differences both ways. */ - leftoversf = matchesf = 0; - for (k = 0; k < CHARCLASS_INTS; ++k) - { - /* Even an optimizing compiler can't know this for sure. */ - int match = matches[k], label = labels[j][k]; - - (leftovers[k] = ~match & label) ? (leftoversf = 1) : 0; - (matches[k] = match & ~label) ? (matchesf = 1) : 0; - } - - /* If there were leftovers, create a new group labeled with them. */ - if (leftoversf) - { - copyset(leftovers, labels[ngrps]); - copyset(intersect, labels[j]); - MALLOC(grps[ngrps].elems, position, d->nleaves); - copy(&grps[j], &grps[ngrps]); - ++ngrps; - } - - /* Put the position in the current group. Note that there is no - reason to call insert() here. */ - grps[j].elems[grps[j].nelem++] = pos; - - /* If every character matching the current position has been - accounted for, we're done. */ - if (! matchesf) - break; - } - - /* If we've passed the last group, and there are still characters - unaccounted for, then we'll have to create a new group. */ - if (j == ngrps) - { - copyset(matches, labels[ngrps]); - zeroset(matches); - MALLOC(grps[ngrps].elems, position, d->nleaves); - grps[ngrps].nelem = 1; - grps[ngrps].elems[0] = pos; - ++ngrps; - } - } - - MALLOC(follows.elems, position, d->nleaves); - MALLOC(tmp.elems, position, d->nleaves); - - /* If we are a searching matcher, the default transition is to a state - containing the positions of state 0, otherwise the default transition - is to fail miserably. */ - if (d->searchflag) - { - wants_newline = 0; - wants_letter = 0; - for (i = 0; i < d->states[0].elems.nelem; ++i) - { - if (PREV_NEWLINE_DEPENDENT(d->states[0].elems.elems[i].constraint)) - wants_newline = 1; - if (PREV_LETTER_DEPENDENT(d->states[0].elems.elems[i].constraint)) - wants_letter = 1; - } - copy(&d->states[0].elems, &follows); - state = state_index(d, &follows, 0, 0); - if (wants_newline) - state_newline = state_index(d, &follows, 1, 0); - else - state_newline = state; - if (wants_letter) - state_letter = state_index(d, &follows, 0, 1); - else - state_letter = state; - for (i = 0; i < NOTCHAR; ++i) - trans[i] = (IS_WORD_CONSTITUENT(i)) ? state_letter : state; - trans[eolbyte] = state_newline; - } - else - for (i = 0; i < NOTCHAR; ++i) - trans[i] = -1; - - for (i = 0; i < ngrps; ++i) - { - follows.nelem = 0; - - /* Find the union of the follows of the positions of the group. - This is a hideously inefficient loop. Fix it someday. */ - for (j = 0; j < grps[i].nelem; ++j) - for (k = 0; k < d->follows[grps[i].elems[j].index].nelem; ++k) - insert(d->follows[grps[i].elems[j].index].elems[k], &follows); - -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - /* If a token in follows.elems is not 1st byte of a multibyte - character, or the states of follows must accept the bytes - which are not 1st byte of the multibyte character. - Then, if a state of follows encounter a byte, it must not be - a 1st byte of a multibyte character nor singlebyte character. - We cansel to add state[0].follows to next state, because - state[0] must accept 1st-byte - - For example, we assume is a certain singlebyte - character, is a certain multibyte character, and the - codepoint of equals the 2nd byte of the codepoint of - . - When state[0] accepts , state[i] transit to state[i+1] - by accepting accepts 1st byte of , and state[i+1] - accepts 2nd byte of , if state[i+1] encounter the - codepoint of , it must not be but 2nd byte of - , so we can not add state[0]. */ - - next_isnt_1st_byte = 0; - for (j = 0; j < follows.nelem; ++j) - { - if (!(d->multibyte_prop[follows.elems[j].index] & 1)) - { - next_isnt_1st_byte = 1; - break; - } - } - } -#endif - - /* If we are building a searching matcher, throw in the positions - of state 0 as well. */ -#ifdef MBS_SUPPORT - if (d->searchflag && (MB_CUR_MAX == 1 || !next_isnt_1st_byte)) -#else - if (d->searchflag) -#endif - for (j = 0; j < d->states[0].elems.nelem; ++j) - insert(d->states[0].elems.elems[j], &follows); - - /* Find out if the new state will want any context information. */ - wants_newline = 0; - if (tstbit(eolbyte, labels[i])) - for (j = 0; j < follows.nelem; ++j) - if (PREV_NEWLINE_DEPENDENT(follows.elems[j].constraint)) - wants_newline = 1; - - wants_letter = 0; - for (j = 0; j < CHARCLASS_INTS; ++j) - if (labels[i][j] & letters[j]) - break; - if (j < CHARCLASS_INTS) - for (j = 0; j < follows.nelem; ++j) - if (PREV_LETTER_DEPENDENT(follows.elems[j].constraint)) - wants_letter = 1; - - /* Find the state(s) corresponding to the union of the follows. */ - state = state_index(d, &follows, 0, 0); - if (wants_newline) - state_newline = state_index(d, &follows, 1, 0); - else - state_newline = state; - if (wants_letter) - state_letter = state_index(d, &follows, 0, 1); - else - state_letter = state; - - /* Set the transitions for each character in the current label. */ - for (j = 0; j < CHARCLASS_INTS; ++j) - for (k = 0; k < INTBITS; ++k) - if (labels[i][j] & 1 << k) - { - int c = j * INTBITS + k; - - if (c == eolbyte) - trans[c] = state_newline; - else if (IS_WORD_CONSTITUENT(c)) - trans[c] = state_letter; - else if (c < NOTCHAR) - trans[c] = state; - } - } - - for (i = 0; i < ngrps; ++i) - free(grps[i].elems); - free(follows.elems); - free(tmp.elems); -} - -/* Some routines for manipulating a compiled dfa's transition tables. - Each state may or may not have a transition table; if it does, and it - is a non-accepting state, then d->trans[state] points to its table. - If it is an accepting state then d->fails[state] points to its table. - If it has no table at all, then d->trans[state] is NULL. - TODO: Improve this comment, get rid of the unnecessary redundancy. */ - -static void -build_state (int s, struct dfa *d) -{ - int *trans; /* The new transition table. */ - int i; - - /* Set an upper limit on the number of transition tables that will ever - exist at once. 1024 is arbitrary. The idea is that the frequently - used transition tables will be quickly rebuilt, whereas the ones that - were only needed once or twice will be cleared away. */ - if (d->trcount >= 1024) - { - for (i = 0; i < d->tralloc; ++i) - if (d->trans[i]) - { - free((ptr_t) d->trans[i]); - d->trans[i] = NULL; - } - else if (d->fails[i]) - { - free((ptr_t) d->fails[i]); - d->fails[i] = NULL; - } - d->trcount = 0; - } - - ++d->trcount; - - /* Set up the success bits for this state. */ - d->success[s] = 0; - if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 1, d->states[s].letter, 0, - s, *d)) - d->success[s] |= 4; - if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 1, - s, *d)) - d->success[s] |= 2; - if (ACCEPTS_IN_CONTEXT(d->states[s].newline, 0, d->states[s].letter, 0, - s, *d)) - d->success[s] |= 1; - - MALLOC(trans, int, NOTCHAR); - dfastate(s, d, trans); - - /* Now go through the new transition table, and make sure that the trans - and fail arrays are allocated large enough to hold a pointer for the - largest state mentioned in the table. */ - for (i = 0; i < NOTCHAR; ++i) - if (trans[i] >= d->tralloc) - { - int oldalloc = d->tralloc; - - while (trans[i] >= d->tralloc) - d->tralloc *= 2; - REALLOC(d->realtrans, int *, d->tralloc + 1); - d->trans = d->realtrans + 1; - REALLOC(d->fails, int *, d->tralloc); - REALLOC(d->success, int, d->tralloc); - while (oldalloc < d->tralloc) - { - d->trans[oldalloc] = NULL; - d->fails[oldalloc++] = NULL; - } - } - - /* Newline is a sentinel. */ - trans[eolbyte] = -1; - - if (ACCEPTING(s, *d)) - d->fails[s] = trans; - else - d->trans[s] = trans; -} - -static void -build_state_zero (struct dfa *d) -{ - d->tralloc = 1; - d->trcount = 0; - CALLOC(d->realtrans, int *, d->tralloc + 1); - d->trans = d->realtrans + 1; - CALLOC(d->fails, int *, d->tralloc); - MALLOC(d->success, int, d->tralloc); - build_state(0, d); -} - -#ifdef MBS_SUPPORT -/* Multibyte character handling sub-routins for dfaexec. */ - -/* Initial state may encounter the byte which is not a singlebyte character - nor 1st byte of a multibyte character. But it is incorrect for initial - state to accept such a byte. - For example, in sjis encoding the regular expression like "\\" accepts - the codepoint 0x5c, but should not accept the 2nd byte of the codepoint - 0x815c. Then Initial state must skip the bytes which are not a singlebyte - character nor 1st byte of a multibyte character. */ -#define SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p) \ - if (s == 0) \ - { \ - while (inputwcs[p - buf_begin] == 0 \ - && mblen_buf[p - buf_begin] > 0 \ - && p < buf_end) \ - ++p; \ - if (p >= end) \ - { \ - free(mblen_buf); \ - free(inputwcs); \ - return (size_t) -1; \ - } \ - } - -static void -realloc_trans_if_necessary(struct dfa *d, int new_state) -{ - /* Make sure that the trans and fail arrays are allocated large enough - to hold a pointer for the new state. */ - if (new_state >= d->tralloc) - { - int oldalloc = d->tralloc; - - while (new_state >= d->tralloc) - d->tralloc *= 2; - REALLOC(d->realtrans, int *, d->tralloc + 1); - d->trans = d->realtrans + 1; - REALLOC(d->fails, int *, d->tralloc); - REALLOC(d->success, int, d->tralloc); - while (oldalloc < d->tralloc) - { - d->trans[oldalloc] = NULL; - d->fails[oldalloc++] = NULL; - } - } -} - -/* Return values of transit_state_singlebyte(), and - transit_state_consume_1char. */ -typedef enum -{ - TRANSIT_STATE_IN_PROGRESS, /* State transition has not finished. */ - TRANSIT_STATE_DONE, /* State transition has finished. */ - TRANSIT_STATE_END_BUFFER /* Reach the end of the buffer. */ -} status_transit_state; - -/* Consume a single byte and transit state from 's' to '*next_state'. - This function is almost same as the state transition routin in dfaexec(). - But state transition is done just once, otherwise matching succeed or - reach the end of the buffer. */ -static status_transit_state -transit_state_singlebyte (struct dfa *d, int s, unsigned char const *p, - int *next_state) -{ - int *t; - int works = s; - - status_transit_state rval = TRANSIT_STATE_IN_PROGRESS; - - while (rval == TRANSIT_STATE_IN_PROGRESS) - { - if ((t = d->trans[works]) != NULL) - { - works = t[*p]; - rval = TRANSIT_STATE_DONE; - if (works < 0) - works = 0; - } - else if (works < 0) - { - if (p == buf_end) - /* At the moment, it must not happen. */ - return TRANSIT_STATE_END_BUFFER; - works = 0; - } - else if (d->fails[works]) - { - works = d->fails[works][*p]; - rval = TRANSIT_STATE_DONE; - } - else - { - build_state(works, d); - } - } - *next_state = works; - return rval; -} - -/* Check whether period can match or not in the current context. If it can, - return the amount of the bytes with which period can match, otherwise - return 0. - `pos' is the position of the period. `index' is the index from the - buf_begin, and it is the current position in the buffer. */ -static int -match_anychar (struct dfa *d, int s, position pos, int index) -{ - int newline = 0; - int letter = 0; - wchar_t wc; - int mbclen; - - wc = inputwcs[index]; - mbclen = (mblen_buf[index] == 0)? 1 : mblen_buf[index]; - - /* Check context. */ - if (wc == (wchar_t)eolbyte) - { - if (!(syntax_bits & RE_DOT_NEWLINE)) - return 0; - newline = 1; - } - else if (wc == (wchar_t)'\0') - { - if (syntax_bits & RE_DOT_NOT_NULL) - return 0; - newline = 1; - } - - if (iswalnum(wc) || wc == L'_') - letter = 1; - - if (!SUCCEEDS_IN_CONTEXT(pos.constraint, d->states[s].newline, - newline, d->states[s].letter, letter)) - return 0; - - return mbclen; -} - -/* Check whether bracket expression can match or not in the current context. - If it can, return the amount of the bytes with which expression can match, - otherwise return 0. - `pos' is the position of the bracket expression. `index' is the index - from the buf_begin, and it is the current position in the buffer. */ -int -match_mb_charset (struct dfa *d, int s, position pos, int index) -{ - int i; - int match; /* Flag which represent that matching succeed. */ - int match_len; /* Length of the character (or collating element) - with which this operator match. */ - size_t op_len; /* Length of the operator. */ - char buffer[128]; - wchar_t wcbuf[6]; - - /* Pointer to the structure to which we are currently reffering. */ - struct mb_char_classes *work_mbc; - - int newline = 0; - int letter = 0; - wchar_t wc; /* Current reffering character. */ - - wc = inputwcs[index]; - - /* Check context. */ - if (wc == (wchar_t)eolbyte) - { - if (!(syntax_bits & RE_DOT_NEWLINE)) - return 0; - newline = 1; - } - else if (wc == (wchar_t)'\0') - { - if (syntax_bits & RE_DOT_NOT_NULL) - return 0; - newline = 1; - } - if (iswalnum(wc) || wc == L'_') - letter = 1; - if (!SUCCEEDS_IN_CONTEXT(pos.constraint, d->states[s].newline, - newline, d->states[s].letter, letter)) - return 0; - - /* Assign the current reffering operator to work_mbc. */ - work_mbc = &(d->mbcsets[(d->multibyte_prop[pos.index]) >> 2]); - match = !work_mbc->invert; - match_len = (mblen_buf[index] == 0)? 1 : mblen_buf[index]; - - /* match with a character class? */ - for (i = 0; inch_classes; i++) - { - if (iswctype((wint_t)wc, work_mbc->ch_classes[i])) - goto charset_matched; - } - - strncpy(buffer, buf_begin + index, match_len); - buffer[match_len] = '\0'; - - /* match with an equivalent class? */ - for (i = 0; inequivs; i++) - { - op_len = strlen(work_mbc->equivs[i]); - strncpy(buffer, buf_begin + index, op_len); - buffer[op_len] = '\0'; - if (strcoll(work_mbc->equivs[i], buffer) == 0) - { - match_len = op_len; - goto charset_matched; - } - } - - /* match with a collating element? */ - for (i = 0; incoll_elems; i++) - { - op_len = strlen(work_mbc->coll_elems[i]); - strncpy(buffer, buf_begin + index, op_len); - buffer[op_len] = '\0'; - - if (strcoll(work_mbc->coll_elems[i], buffer) == 0) - { - match_len = op_len; - goto charset_matched; - } - } - - wcbuf[0] = wc; - wcbuf[1] = wcbuf[3] = wcbuf[5] = '\0'; - - /* match with a range? */ - for (i = 0; inranges; i++) - { - wcbuf[2] = work_mbc->range_sts[i]; - wcbuf[4] = work_mbc->range_ends[i]; - - if (wcscoll(wcbuf, wcbuf+2) >= 0 && - wcscoll(wcbuf+4, wcbuf) >= 0) - goto charset_matched; - } - - /* match with a character? */ - if (case_fold) - wc = towlower (wc); - for (i = 0; inchars; i++) - { - if (wc == work_mbc->chars[i]) - goto charset_matched; - } - - match = !match; - - charset_matched: - return match ? match_len : 0; -} - -/* Check each of `d->states[s].mbps.elem' can match or not. Then return the - array which corresponds to `d->states[s].mbps.elem' and each element of - the array contains the amount of the bytes with which the element can - match. - `index' is the index from the buf_begin, and it is the current position - in the buffer. - Caller MUST free the array which this function return. */ -static int* -check_matching_with_multibyte_ops (struct dfa *d, int s, int index) -{ - int i; - int* rarray; - - MALLOC(rarray, int, d->states[s].mbps.nelem); - for (i = 0; i < d->states[s].mbps.nelem; ++i) - { - position pos = d->states[s].mbps.elems[i]; - switch(d->tokens[pos.index]) - { - case ANYCHAR: - rarray[i] = match_anychar(d, s, pos, index); - break; - case MBCSET: - rarray[i] = match_mb_charset(d, s, pos, index); - break; - default: - break; /* can not happen. */ - } - } - return rarray; -} - -/* Consume a single character and enumerate all of the positions which can - be next position from the state `s'. - `match_lens' is the input. It can be NULL, but it can also be the output - of check_matching_with_multibyte_ops() for optimization. - `mbclen' and `pps' are the output. `mbclen' is the length of the - character consumed, and `pps' is the set this function enumerate. */ -static status_transit_state -transit_state_consume_1char (struct dfa *d, int s, unsigned char const **pp, - int *match_lens, int *mbclen, position_set *pps) -{ - int i, j; - int s1, s2; - int* work_mbls; - status_transit_state rs = TRANSIT_STATE_DONE; - - /* Calculate the length of the (single/multi byte) character - to which p points. */ - *mbclen = (mblen_buf[*pp - buf_begin] == 0)? 1 - : mblen_buf[*pp - buf_begin]; - - /* Calculate the state which can be reached from the state `s' by - consuming `*mbclen' single bytes from the buffer. */ - s1 = s; - for (i = 0; i < *mbclen; i++) - { - s2 = s1; - rs = transit_state_singlebyte(d, s2, (*pp)++, &s1); - } - /* Copy the positions contained by `s1' to the set `pps'. */ - copy(&(d->states[s1].elems), pps); - - /* Check (inputed)match_lens, and initialize if it is NULL. */ - if (match_lens == NULL && d->states[s].mbps.nelem != 0) - work_mbls = check_matching_with_multibyte_ops(d, s, *pp - buf_begin); - else - work_mbls = match_lens; - - /* Add all of the positions which can be reached from `s' by consuming - a single character. */ - for (i = 0; i < d->states[s].mbps.nelem ; i++) - { - if (work_mbls[i] == *mbclen) - for (j = 0; j < d->follows[d->states[s].mbps.elems[i].index].nelem; - j++) - insert(d->follows[d->states[s].mbps.elems[i].index].elems[j], - pps); - } - - if (match_lens == NULL && work_mbls != NULL) - free(work_mbls); - return rs; -} - -/* Transit state from s, then return new state and update the pointer of the - buffer. This function is for some operator which can match with a multi- - byte character or a collating element(which may be multi characters). */ -static int -transit_state (struct dfa *d, int s, unsigned char const **pp) -{ - int s1; - int mbclen; /* The length of current input multibyte character. */ - int maxlen = 0; - int i, j; - int *match_lens = NULL; - int nelem = d->states[s].mbps.nelem; /* Just a alias. */ - position_set follows; - unsigned char const *p1 = *pp; - status_transit_state rs; - wchar_t wc; - - if (nelem > 0) - /* This state has (a) multibyte operator(s). - We check whether each of them can match or not. */ - { - /* Note: caller must free the return value of this function. */ - match_lens = check_matching_with_multibyte_ops(d, s, *pp - buf_begin); - - for (i = 0; i < nelem; i++) - /* Search the operator which match the longest string, - in this state. */ - { - if (match_lens[i] > maxlen) - maxlen = match_lens[i]; - } - } - - if (nelem == 0 || maxlen == 0) - /* This state has no multibyte operator which can match. - We need to check only one singlebyte character. */ - { - status_transit_state rs; - rs = transit_state_singlebyte(d, s, *pp, &s1); - - /* We must update the pointer if state transition succeeded. */ - if (rs == TRANSIT_STATE_DONE) - ++*pp; - - if (match_lens != NULL) - free(match_lens); - return s1; - } - - /* This state has some operators which can match a multibyte character. */ - follows.nelem = 0; - MALLOC(follows.elems, position, d->nleaves); - - /* `maxlen' may be longer than the length of a character, because it may - not be a character but a (multi character) collating element. - We enumerate all of the positions which `s' can reach by consuming - `maxlen' bytes. */ - rs = transit_state_consume_1char(d, s, pp, match_lens, &mbclen, &follows); - - wc = inputwcs[*pp - mbclen - buf_begin]; - s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc)); - realloc_trans_if_necessary(d, s1); - - while (*pp - p1 < maxlen) - { - follows.nelem = 0; - rs = transit_state_consume_1char(d, s1, pp, NULL, &mbclen, &follows); - - for (i = 0; i < nelem ; i++) - { - if (match_lens[i] == *pp - p1) - for (j = 0; - j < d->follows[d->states[s1].mbps.elems[i].index].nelem; j++) - insert(d->follows[d->states[s1].mbps.elems[i].index].elems[j], - &follows); - } - - wc = inputwcs[*pp - mbclen - buf_begin]; - s1 = state_index(d, &follows, wc == L'\n', iswalnum(wc)); - realloc_trans_if_necessary(d, s1); - } - free(match_lens); - free(follows.elems); - return s1; -} - -#endif - -/* Search through a buffer looking for a match to the given struct dfa. - Find the first occurrence of a string matching the regexp in the buffer, - and the shortest possible version thereof. Return the offset of the first - character after the match, or (size_t) -1 if none is found. BEGIN points to - the beginning of the buffer, and SIZE is the size of the buffer. If SIZE - is nonzero, BEGIN[SIZE - 1] must be a newline. BACKREF points to a place - where we're supposed to store a 1 if backreferencing happened and the - match needs to be verified by a backtracking matcher. Otherwise - we store a 0 in *backref. */ -size_t -dfaexec (struct dfa *d, char const *begin, size_t size, int *backref) -{ - register int s; /* Current state. */ - register unsigned char const *p; /* Current input character. */ - register unsigned char const *end; /* One past the last input character. */ - register int **trans, *t; /* Copy of d->trans so it can be optimized - into a register. */ - register unsigned char eol = eolbyte; /* Likewise for eolbyte. */ - static int sbit[NOTCHAR]; /* Table for anding with d->success. */ - static int sbit_init; - - if (! sbit_init) - { - int i; - - sbit_init = 1; - for (i = 0; i < NOTCHAR; ++i) - sbit[i] = (IS_WORD_CONSTITUENT(i)) ? 2 : 1; - sbit[eol] = 4; - } - - if (! d->tralloc) - build_state_zero(d); - - s = 0; - p = (unsigned char const *) begin; - end = p + size; - trans = d->trans; - -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - int remain_bytes, i; - buf_begin = begin; - buf_end = end; - - /* initialize mblen_buf, and inputwcs. */ - MALLOC(mblen_buf, unsigned char, end - (unsigned char const *)begin + 2); - MALLOC(inputwcs, wchar_t, end - (unsigned char const *)begin + 2); - memset(&mbs, 0, sizeof(mbstate_t)); - remain_bytes = 0; - for (i = 0; i < end - (unsigned char const *)begin + 1; i++) - { - if (remain_bytes == 0) - { - remain_bytes - = mbrtowc(inputwcs + i, begin + i, - end - (unsigned char const *)begin - i + 1, &mbs); - if (remain_bytes <= 1) - { - remain_bytes = 0; - inputwcs[i] = (wchar_t)begin[i]; - mblen_buf[i] = 0; - } - else - { - mblen_buf[i] = remain_bytes; - remain_bytes--; - } - } - else - { - mblen_buf[i] = remain_bytes; - inputwcs[i] = 0; - remain_bytes--; - } - } - mblen_buf[i] = 0; - inputwcs[i] = 0; /* sentinel */ - } -#endif /* MBS_SUPPORT */ - - for (;;) - { -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - while ((t = trans[s])) - { - if (d->states[s].mbps.nelem != 0) - { - /* Can match with a multibyte character( and multi character - collating element). */ - unsigned char const *nextp; - - SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p); - - nextp = p; - s = transit_state(d, s, &nextp); - p = nextp; - - /* Trans table might be updated. */ - trans = d->trans; - } - else - { - SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p); - s = t[*p++]; - } - } - else -#endif /* MBS_SUPPORT */ - while ((t = trans[s])) - s = t[*p++]; - - if (s < 0) - { - if (p == end) - { -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - free(mblen_buf); - free(inputwcs); - } -#endif /* MBS_SUPPORT */ - return (size_t) -1; - } - s = 0; - } - else if ((t = d->fails[s])) - { - if (d->success[s] & sbit[*p]) - { - if (backref) - *backref = (d->states[s].backref != 0); -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - free(mblen_buf); - free(inputwcs); - } -#endif /* MBS_SUPPORT */ - return (char const *) p - begin; - } - -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p); - if (d->states[s].mbps.nelem != 0) - { - /* Can match with a multibyte character( and multi - character collating element). */ - unsigned char const *nextp; - nextp = p; - s = transit_state(d, s, &nextp); - p = nextp; - - /* Trans table might be updated. */ - trans = d->trans; - } - else - s = t[*p++]; - } - else -#endif /* MBS_SUPPORT */ - s = t[*p++]; - } - else - { - build_state(s, d); - trans = d->trans; - } - } -} - -/* Initialize the components of a dfa that the other routines don't - initialize for themselves. */ -void -dfainit (struct dfa *d) -{ - d->calloc = 1; - MALLOC(d->charclasses, charclass, d->calloc); - d->cindex = 0; - - d->talloc = 1; - MALLOC(d->tokens, token, d->talloc); - d->tindex = d->depth = d->nleaves = d->nregexps = 0; -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - d->nmultibyte_prop = 1; - MALLOC(d->multibyte_prop, int, d->nmultibyte_prop); - d->nmbcsets = 0; - d->mbcsets_alloc = 1; - MALLOC(d->mbcsets, struct mb_char_classes, d->mbcsets_alloc); - } -#endif - - d->searchflag = 0; - d->tralloc = 0; - - d->musts = 0; -} - -/* Parse and analyze a single string of the given length. */ -void -dfacomp (char const *s, size_t len, struct dfa *d, int searchflag) -{ - if (case_fold) /* dummy folding in service of dfamust() */ - { - char *lcopy; - int i; - - lcopy = malloc(len); - if (!lcopy) - dfaerror(_("out of memory")); - - /* This is a kludge. */ - case_fold = 0; - for (i = 0; i < len; ++i) - if (ISUPPER ((unsigned char) s[i])) - lcopy[i] = tolower ((unsigned char) s[i]); - else - lcopy[i] = s[i]; - - dfainit(d); - dfaparse(lcopy, len, d); - free(lcopy); - dfamust(d); - d->cindex = d->tindex = d->depth = d->nleaves = d->nregexps = 0; - case_fold = 1; - dfaparse(s, len, d); - dfaanalyze(d, searchflag); - } - else - { - dfainit(d); - dfaparse(s, len, d); - dfamust(d); - dfaanalyze(d, searchflag); - } -} - -/* Free the storage held by the components of a dfa. */ -void -dfafree (struct dfa *d) -{ - int i; - struct dfamust *dm, *ndm; - - free((ptr_t) d->charclasses); - free((ptr_t) d->tokens); - -#ifdef MBS_SUPPORT - if (MB_CUR_MAX > 1) - { - free((ptr_t) d->multibyte_prop); - for (i = 0; i < d->nmbcsets; ++i) - { - int j; - struct mb_char_classes *p = &(d->mbcsets[i]); - if (p->chars != NULL) - free(p->chars); - if (p->ch_classes != NULL) - free(p->ch_classes); - if (p->range_sts != NULL) - free(p->range_sts); - if (p->range_ends != NULL) - free(p->range_ends); - - for (j = 0; j < p->nequivs; ++j) - free(p->equivs[j]); - if (p->equivs != NULL) - free(p->equivs); - - for (j = 0; j < p->ncoll_elems; ++j) - free(p->coll_elems[j]); - if (p->coll_elems != NULL) - free(p->coll_elems); - } - free((ptr_t) d->mbcsets); - } -#endif /* MBS_SUPPORT */ - - for (i = 0; i < d->sindex; ++i) - free((ptr_t) d->states[i].elems.elems); - free((ptr_t) d->states); - for (i = 0; i < d->tindex; ++i) - if (d->follows[i].elems) - free((ptr_t) d->follows[i].elems); - free((ptr_t) d->follows); - for (i = 0; i < d->tralloc; ++i) - if (d->trans[i]) - free((ptr_t) d->trans[i]); - else if (d->fails[i]) - free((ptr_t) d->fails[i]); - if (d->realtrans) free((ptr_t) d->realtrans); - if (d->fails) free((ptr_t) d->fails); - if (d->success) free((ptr_t) d->success); - for (dm = d->musts; dm; dm = ndm) - { - ndm = dm->next; - free(dm->must); - free((ptr_t) dm); - } -} - -/* Having found the postfix representation of the regular expression, - try to find a long sequence of characters that must appear in any line - containing the r.e. - Finding a "longest" sequence is beyond the scope here; - we take an easy way out and hope for the best. - (Take "(ab|a)b"--please.) - - We do a bottom-up calculation of sequences of characters that must appear - in matches of r.e.'s represented by trees rooted at the nodes of the postfix - representation: - sequences that must appear at the left of the match ("left") - sequences that must appear at the right of the match ("right") - lists of sequences that must appear somewhere in the match ("in") - sequences that must constitute the match ("is") - - When we get to the root of the tree, we use one of the longest of its - calculated "in" sequences as our answer. The sequence we find is returned in - d->must (where "d" is the single argument passed to "dfamust"); - the length of the sequence is returned in d->mustn. - - The sequences calculated for the various types of node (in pseudo ANSI c) - are shown below. "p" is the operand of unary operators (and the left-hand - operand of binary operators); "q" is the right-hand operand of binary - operators. - - "ZERO" means "a zero-length sequence" below. - - Type left right is in - ---- ---- ----- -- -- - char c # c # c # c # c - - ANYCHAR ZERO ZERO ZERO ZERO - - MBCSET ZERO ZERO ZERO ZERO - - CSET ZERO ZERO ZERO ZERO - - STAR ZERO ZERO ZERO ZERO - - QMARK ZERO ZERO ZERO ZERO - - PLUS p->left p->right ZERO p->in - - CAT (p->is==ZERO)? (q->is==ZERO)? (p->is!=ZERO && p->in plus - p->left : q->right : q->is!=ZERO) ? q->in plus - p->is##q->left p->right##q->is p->is##q->is : p->right##q->left - ZERO - - OR longest common longest common (do p->is and substrings common to - leading trailing q->is have same p->in and q->in - (sub)sequence (sub)sequence length and - of p->left of p->right content) ? - and q->left and q->right p->is : NULL - - If there's anything else we recognize in the tree, all four sequences get set - to zero-length sequences. If there's something we don't recognize in the tree, - we just return a zero-length sequence. - - Break ties in favor of infrequent letters (choosing 'zzz' in preference to - 'aaa')? - - And. . .is it here or someplace that we might ponder "optimizations" such as - egrep 'psi|epsilon' -> egrep 'psi' - egrep 'pepsi|epsilon' -> egrep 'epsi' - (Yes, we now find "epsi" as a "string - that must occur", but we might also - simplify the *entire* r.e. being sought) - grep '[c]' -> grep 'c' - grep '(ab|a)b' -> grep 'ab' - grep 'ab*' -> grep 'a' - grep 'a*b' -> grep 'b' - - There are several issues: - - Is optimization easy (enough)? - - Does optimization actually accomplish anything, - or is the automaton you get from "psi|epsilon" (for example) - the same as the one you get from "psi" (for example)? - - Are optimizable r.e.'s likely to be used in real-life situations - (something like 'ab*' is probably unlikely; something like is - 'psi|epsilon' is likelier)? */ - -static char * -icatalloc (char *old, char *new) -{ - char *result; - size_t oldsize, newsize; - - newsize = (new == NULL) ? 0 : strlen(new); - if (old == NULL) - oldsize = 0; - else if (newsize == 0) - return old; - else oldsize = strlen(old); - if (old == NULL) - result = (char *) malloc(newsize + 1); - else - result = (char *) realloc((void *) old, oldsize + newsize + 1); - if (result != NULL && new != NULL) - (void) strcpy(result + oldsize, new); - return result; -} - -static char * -icpyalloc (char *string) -{ - return icatalloc((char *) NULL, string); -} - -static char * -istrstr (char *lookin, char *lookfor) -{ - char *cp; - size_t len; - - len = strlen(lookfor); - for (cp = lookin; *cp != '\0'; ++cp) - if (strncmp(cp, lookfor, len) == 0) - return cp; - return NULL; -} - -static void -ifree (char *cp) -{ - if (cp != NULL) - free(cp); -} - -static void -freelist (char **cpp) -{ - int i; - - if (cpp == NULL) - return; - for (i = 0; cpp[i] != NULL; ++i) - { - free(cpp[i]); - cpp[i] = NULL; - } -} - -static char ** -enlist (char **cpp, char *new, size_t len) -{ - int i, j; - - if (cpp == NULL) - return NULL; - if ((new = icpyalloc(new)) == NULL) - { - freelist(cpp); - return NULL; - } - new[len] = '\0'; - /* Is there already something in the list that's new (or longer)? */ - for (i = 0; cpp[i] != NULL; ++i) - if (istrstr(cpp[i], new) != NULL) - { - free(new); - return cpp; - } - /* Eliminate any obsoleted strings. */ - j = 0; - while (cpp[j] != NULL) - if (istrstr(new, cpp[j]) == NULL) - ++j; - else - { - free(cpp[j]); - if (--i == j) - break; - cpp[j] = cpp[i]; - cpp[i] = NULL; - } - /* Add the new string. */ - cpp = (char **) realloc((char *) cpp, (i + 2) * sizeof *cpp); - if (cpp == NULL) - return NULL; - cpp[i] = new; - cpp[i + 1] = NULL; - return cpp; -} - -/* Given pointers to two strings, return a pointer to an allocated - list of their distinct common substrings. Return NULL if something - seems wild. */ -static char ** -comsubs (char *left, char *right) -{ - char **cpp; - char *lcp; - char *rcp; - size_t i, len; - - if (left == NULL || right == NULL) - return NULL; - cpp = (char **) malloc(sizeof *cpp); - if (cpp == NULL) - return NULL; - cpp[0] = NULL; - for (lcp = left; *lcp != '\0'; ++lcp) - { - len = 0; - rcp = strchr (right, *lcp); - while (rcp != NULL) - { - for (i = 1; lcp[i] != '\0' && lcp[i] == rcp[i]; ++i) - continue; - if (i > len) - len = i; - rcp = strchr (rcp + 1, *lcp); - } - if (len == 0) - continue; - if ((cpp = enlist(cpp, lcp, len)) == NULL) - break; - } - return cpp; -} - -static char ** -addlists (char **old, char **new) -{ - int i; - - if (old == NULL || new == NULL) - return NULL; - for (i = 0; new[i] != NULL; ++i) - { - old = enlist(old, new[i], strlen(new[i])); - if (old == NULL) - break; - } - return old; -} - -/* Given two lists of substrings, return a new list giving substrings - common to both. */ -static char ** -inboth (char **left, char **right) -{ - char **both; - char **temp; - int lnum, rnum; - - if (left == NULL || right == NULL) - return NULL; - both = (char **) malloc(sizeof *both); - if (both == NULL) - return NULL; - both[0] = NULL; - for (lnum = 0; left[lnum] != NULL; ++lnum) - { - for (rnum = 0; right[rnum] != NULL; ++rnum) - { - temp = comsubs(left[lnum], right[rnum]); - if (temp == NULL) - { - freelist(both); - return NULL; - } - both = addlists(both, temp); - freelist(temp); - free(temp); - if (both == NULL) - return NULL; - } - } - return both; -} - -typedef struct -{ - char **in; - char *left; - char *right; - char *is; -} must; - -static void -resetmust (must *mp) -{ - mp->left[0] = mp->right[0] = mp->is[0] = '\0'; - freelist(mp->in); -} - -static void -dfamust (struct dfa *dfa) -{ - must *musts; - must *mp; - char *result; - int ri; - int i; - int exact; - token t; - static must must0; - struct dfamust *dm; - static char empty_string[] = ""; - - result = empty_string; - exact = 0; - musts = (must *) malloc((dfa->tindex + 1) * sizeof *musts); - if (musts == NULL) - return; - mp = musts; - for (i = 0; i <= dfa->tindex; ++i) - mp[i] = must0; - for (i = 0; i <= dfa->tindex; ++i) - { - mp[i].in = (char **) malloc(sizeof *mp[i].in); - mp[i].left = malloc(2); - mp[i].right = malloc(2); - mp[i].is = malloc(2); - if (mp[i].in == NULL || mp[i].left == NULL || - mp[i].right == NULL || mp[i].is == NULL) - goto done; - mp[i].left[0] = mp[i].right[0] = mp[i].is[0] = '\0'; - mp[i].in[0] = NULL; - } -#ifdef DEBUG - fprintf(stderr, "dfamust:\n"); - for (i = 0; i < dfa->tindex; ++i) - { - fprintf(stderr, " %d:", i); - prtok(dfa->tokens[i]); - } - putc('\n', stderr); -#endif - for (ri = 0; ri < dfa->tindex; ++ri) - { - switch (t = dfa->tokens[ri]) - { - case LPAREN: - case RPAREN: - goto done; /* "cannot happen" */ - case EMPTY: - case BEGLINE: - case ENDLINE: - case BEGWORD: - case ENDWORD: - case LIMWORD: - case NOTLIMWORD: - case BACKREF: - resetmust(mp); - break; - case STAR: - case QMARK: - if (mp <= musts) - goto done; /* "cannot happen" */ - --mp; - resetmust(mp); - break; - case OR: - case ORTOP: - if (mp < &musts[2]) - goto done; /* "cannot happen" */ - { - char **new; - must *lmp; - must *rmp; - int j, ln, rn, n; - - rmp = --mp; - lmp = --mp; - /* Guaranteed to be. Unlikely, but. . . */ - if (strcmp(lmp->is, rmp->is) != 0) - lmp->is[0] = '\0'; - /* Left side--easy */ - i = 0; - while (lmp->left[i] != '\0' && lmp->left[i] == rmp->left[i]) - ++i; - lmp->left[i] = '\0'; - /* Right side */ - ln = strlen(lmp->right); - rn = strlen(rmp->right); - n = ln; - if (n > rn) - n = rn; - for (i = 0; i < n; ++i) - if (lmp->right[ln - i - 1] != rmp->right[rn - i - 1]) - break; - for (j = 0; j < i; ++j) - lmp->right[j] = lmp->right[(ln - i) + j]; - lmp->right[j] = '\0'; - new = inboth(lmp->in, rmp->in); - if (new == NULL) - goto done; - freelist(lmp->in); - free((char *) lmp->in); - lmp->in = new; - } - break; - case PLUS: - if (mp <= musts) - goto done; /* "cannot happen" */ - --mp; - mp->is[0] = '\0'; - break; - case END: - if (mp != &musts[1]) - goto done; /* "cannot happen" */ - for (i = 0; musts[0].in[i] != NULL; ++i) - if (strlen(musts[0].in[i]) > strlen(result)) - result = musts[0].in[i]; - if (strcmp(result, musts[0].is) == 0) - exact = 1; - goto done; - case CAT: - if (mp < &musts[2]) - goto done; /* "cannot happen" */ - { - must *lmp; - must *rmp; - - rmp = --mp; - lmp = --mp; - /* In. Everything in left, plus everything in - right, plus catenation of - left's right and right's left. */ - lmp->in = addlists(lmp->in, rmp->in); - if (lmp->in == NULL) - goto done; - if (lmp->right[0] != '\0' && - rmp->left[0] != '\0') - { - char *tp; - - tp = icpyalloc(lmp->right); - if (tp == NULL) - goto done; - tp = icatalloc(tp, rmp->left); - if (tp == NULL) - goto done; - lmp->in = enlist(lmp->in, tp, - strlen(tp)); - free(tp); - if (lmp->in == NULL) - goto done; - } - /* Left-hand */ - if (lmp->is[0] != '\0') - { - lmp->left = icatalloc(lmp->left, - rmp->left); - if (lmp->left == NULL) - goto done; - } - /* Right-hand */ - if (rmp->is[0] == '\0') - lmp->right[0] = '\0'; - lmp->right = icatalloc(lmp->right, rmp->right); - if (lmp->right == NULL) - goto done; - /* Guaranteed to be */ - if (lmp->is[0] != '\0' && rmp->is[0] != '\0') - { - lmp->is = icatalloc(lmp->is, rmp->is); - if (lmp->is == NULL) - goto done; - } - else - lmp->is[0] = '\0'; - } - break; - default: - if (t < END) - { - /* "cannot happen" */ - goto done; - } - else if (t == '\0') - { - /* not on *my* shift */ - goto done; - } - else if (t >= CSET -#ifdef MBS_SUPPORT - || t == ANYCHAR - || t == MBCSET -#endif /* MBS_SUPPORT */ - ) - { - /* easy enough */ - resetmust(mp); - } - else - { - /* plain character */ - resetmust(mp); - mp->is[0] = mp->left[0] = mp->right[0] = t; - mp->is[1] = mp->left[1] = mp->right[1] = '\0'; - mp->in = enlist(mp->in, mp->is, (size_t)1); - if (mp->in == NULL) - goto done; - } - break; - } -#ifdef DEBUG - fprintf(stderr, " node: %d:", ri); - prtok(dfa->tokens[ri]); - fprintf(stderr, "\n in:"); - for (i = 0; mp->in[i]; ++i) - fprintf(stderr, " \"%s\"", mp->in[i]); - fprintf(stderr, "\n is: \"%s\"\n", mp->is); - fprintf(stderr, " left: \"%s\"\n", mp->left); - fprintf(stderr, " right: \"%s\"\n", mp->right); -#endif - ++mp; - } - done: - if (strlen(result)) - { - dm = (struct dfamust *) malloc(sizeof (struct dfamust)); - dm->exact = exact; - dm->must = malloc(strlen(result) + 1); - strcpy(dm->must, result); - dm->next = dfa->musts; - dfa->musts = dm; - } - mp = musts; - for (i = 0; i <= dfa->tindex; ++i) - { - freelist(mp[i].in); - ifree((char *) mp[i].in); - ifree(mp[i].left); - ifree(mp[i].right); - ifree(mp[i].is); - } - free((char *) mp); -} -/* vim:set shiftwidth=2: */ Index: gnu/usr.bin/grep/error.h =================================================================== --- gnu/usr.bin/grep/error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - - - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined (__STDC__) && __STDC__ - -/* Print a message with `fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ - -extern void error (int status, int errnum, const char *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -extern void error_at_line (int status, int errnum, const char *fname, - unsigned int lineno, const char *format, ...) - __attribute__ ((__format__ (__printf__, 5, 6))); - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -extern void (*error_print_progname) (void); - -#else -void error (); -void error_at_line (); -extern void (*error_print_progname) (); -#endif - -/* This variable is incremented each time `error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ Index: gnu/usr.bin/grep/error.c =================================================================== --- gnu/usr.bin/grep/error.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000 Free Software Foundation, Inc. - - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Written by David MacKenzie . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#if HAVE_LIBINTL_H -# include -#endif - -#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC -# if __STDC__ -# include -# define VA_START(args, lastarg) va_start(args, lastarg) -# else -# include -# define VA_START(args, lastarg) va_start(args) -# endif -#else -# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 -# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; -#endif - -#if STDC_HEADERS || _LIBC -# include -# include -#else -void exit (); -#endif - -#include "error.h" - -#ifndef HAVE_DECL_STRERROR_R -"this configure-time declaration test was not run" -#endif -#if !HAVE_DECL_STRERROR_R -char *strerror_r (); -#endif - -#ifndef _ -# define _(String) String -#endif - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -void (*error_print_progname) ( -#if __STDC__ - 0 - void -#endif - ); - -/* This variable is incremented each time `error' is called. */ -unsigned int error_message_count; - -#ifdef _LIBC -/* In the GNU C library, there is a predefined variable for this. */ - -# define program_name program_invocation_name -# include - -/* In GNU libc we want do not want to use the common name `error' directly. - Instead make it a weak alias. */ -# define error __error -# define error_at_line __error_at_line - -# ifdef USE_IN_LIBIO -# include -# define fflush(s) _IO_fflush (s) -# endif - -#else /* not _LIBC */ - -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; - -# ifdef HAVE_STRERROR_R -# define __strerror_r strerror_r -# else -# if HAVE_STRERROR -# ifndef strerror /* On some systems, strerror is a macro */ -char *strerror (); -# endif -# else -static char * -private_strerror (errnum) - int errnum; -{ - extern char *sys_errlist[]; - extern int sys_nerr; - - if (errnum > 0 && errnum <= sys_nerr) - return _(sys_errlist[errnum]); - return _("Unknown system error"); -} -# define strerror private_strerror -# endif /* HAVE_STRERROR */ -# endif /* HAVE_STRERROR_R */ -#endif /* not _LIBC */ - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args. - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status STATUS if it is nonzero. */ -/* VARARGS */ - -void -#if defined VA_START && __STDC__ -error (int status, int errnum, const char *message, ...) -#else -error (status, errnum, message, va_alist) - int status; - int errnum; - char *message; - va_dcl -#endif -{ -#ifdef VA_START - va_list args; -#endif - - if (error_print_progname) - (*error_print_progname) (); - else - { - fflush (stdout); - fprintf (stderr, "%s: ", program_name); - } - -#ifdef VA_START - VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif - - ++error_message_count; - if (errnum) - { -#if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; -# if HAVE_WORKING_STRERROR_R || _LIBC - fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); -# else - /* Don't use __strerror_r's return value because on some systems - (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ - __strerror_r (errnum, errbuf, sizeof errbuf); - fprintf (stderr, ": %s", errbuf); -# endif -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -} - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -int error_one_per_line; - -void -#if defined VA_START && __STDC__ -error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) -#else -error_at_line (status, errnum, file_name, line_number, message, va_alist) - int status; - int errnum; - const char *file_name; - unsigned int line_number; - char *message; - va_dcl -#endif -{ -#ifdef VA_START - va_list args; -#endif - - if (error_one_per_line) - { - static const char *old_file_name; - static unsigned int old_line_number; - - if (old_line_number == line_number && - (file_name == old_file_name || !strcmp (old_file_name, file_name))) - /* Simply return and print nothing. */ - return; - - old_file_name = file_name; - old_line_number = line_number; - } - - if (error_print_progname) - (*error_print_progname) (); - else - { - fflush (stdout); - fprintf (stderr, "%s:", program_name); - } - - if (file_name != NULL) - fprintf (stderr, "%s:%d: ", file_name, line_number); - -#ifdef VA_START - VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif - - ++error_message_count; - if (errnum) - { -#if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; -# if HAVE_WORKING_STRERROR_R || _LIBC - fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); -# else - /* Don't use __strerror_r's return value because on some systems - (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ - __strerror_r (errnum, errbuf, sizeof errbuf); - fprintf (stderr, ": %s", errbuf); -# endif -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -} - -#ifdef _LIBC -/* Make the weak alias. */ -# undef error -# undef error_at_line -weak_alias (__error, error) -weak_alias (__error_at_line, error_at_line) -#endif Index: gnu/usr.bin/grep/exclude.h =================================================================== --- gnu/usr.bin/grep/exclude.h +++ /dev/null @@ -1,35 +0,0 @@ -/* exclude.h -- declarations for excluding file names - Copyright 1992, 1993, 1994, 1997, 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert */ - -#ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -struct exclude; - -struct exclude *new_exclude PARAMS ((void)); -void add_exclude PARAMS ((struct exclude *, char const *)); -int add_exclude_file PARAMS ((void (*) (struct exclude *, char const *), - struct exclude *, char const *, char)); -int excluded_filename PARAMS ((struct exclude const *, char const *, int)); Index: gnu/usr.bin/grep/exclude.c =================================================================== --- gnu/usr.bin/grep/exclude.c +++ /dev/null @@ -1,128 +0,0 @@ -/* exclude.c -- exclude file names - Copyright 1992, 1993, 1994, 1997, 1999, 2000 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#ifndef errno -extern int errno; -#endif -#include -#include -#include -#include - -void *xmalloc PARAMS ((size_t)); -void *xrealloc PARAMS ((void *, size_t)); - -/* Keep track of excluded file name patterns. */ - -struct exclude - { - char const **exclude; - int exclude_alloc; - int exclude_count; - }; - -struct exclude * -new_exclude (void) -{ - struct exclude *ex = (struct exclude *) xmalloc (sizeof (struct exclude)); - ex->exclude_count = 0; - ex->exclude_alloc = 64; - ex->exclude = (char const **) xmalloc (ex->exclude_alloc * sizeof (char *)); - return ex; -} - -int -excluded_filename (struct exclude const *ex, char const *f, int options) -{ - char const * const *exclude = ex->exclude; - int exclude_count = ex->exclude_count; - int i; - - for (i = 0; i < exclude_count; i++) - if (fnmatch (exclude[i], f, options) == 0) - return 1; - - return 0; -} - -void -add_exclude (struct exclude *ex, char const *pattern) -{ - if (ex->exclude_alloc <= ex->exclude_count) - ex->exclude = (char const **) xrealloc (ex->exclude, - ((ex->exclude_alloc *= 2) - * sizeof (char *))); - - ex->exclude[ex->exclude_count++] = pattern; -} - -int -add_exclude_file (void (*add_func) PARAMS ((struct exclude *, char const *)), - struct exclude *ex, char const *filename, char line_end) -{ - int use_stdin = filename[0] == '-' && !filename[1]; - FILE *in; - char *buf; - char *p; - char const *pattern; - char const *lim; - size_t buf_alloc = 1024; - size_t buf_count = 0; - int c; - int e = 0; - - if (use_stdin) - in = stdin; - else if (! (in = fopen (filename, "r"))) - return -1; - - buf = xmalloc (buf_alloc); - - while ((c = getc (in)) != EOF) - { - buf[buf_count++] = c; - if (buf_count == buf_alloc) - buf = xrealloc (buf, buf_alloc *= 2); - } - - buf = xrealloc (buf, buf_count + 1); - - if (ferror (in)) - e = errno; - - if (!use_stdin && fclose (in) != 0) - e = errno; - - for (pattern = p = buf, lim = buf + buf_count; p <= lim; p++) - if (p < lim ? *p == line_end : buf < p && p[-1]) - { - *p = '\0'; - (*add_func) (ex, pattern); - pattern = p + 1; - } - - errno = e; - return e ? -1 : 0; -} Index: gnu/usr.bin/grep/getpagesize.h =================================================================== --- gnu/usr.bin/grep/getpagesize.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Emulate getpagesize on systems that lack it. */ - -/* $FreeBSD$ */ - -#ifndef HAVE_GETPAGESIZE - -#if !defined getpagesize && defined __BEOS__ -# include -# define getpagesize() B_PAGE_SIZE -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#if !defined getpagesize && defined _SC_PAGESIZE -# if !(defined VMS && __VMS_VER < 70000000) -# define getpagesize() sysconf (_SC_PAGESIZE) -# endif -#endif - -#if !defined getpagesize && defined VMS -# ifdef __ALPHA -# define getpagesize() 8192 -# else -# define getpagesize() 512 -# endif -#endif - -#ifndef getpagesize -# include -# ifdef EXEC_PAGESIZE -# define getpagesize() EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define CLSIZE 1 -# endif -# define getpagesize() (NBPG * CLSIZE) -# else -# ifdef NBPC -# define getpagesize() NBPC -# endif -# endif -# endif -#endif - -#endif /* not HAVE_GETPAGESIZE */ Index: gnu/usr.bin/grep/grep.h =================================================================== --- gnu/usr.bin/grep/grep.h +++ /dev/null @@ -1,44 +0,0 @@ -/* grep.h - interface to grep driver for searching subroutines. - Copyright (C) 1992, 1998, 2001 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* $FreeBSD$ */ - -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__ -# define __attribute__(x) -#endif - -/* Grep.c expects the matchers vector to be terminated - by an entry with a NULL compile, and to contain at least - an entry named "default". */ - -extern struct matcher -{ - char name[8]; - void (*compile) PARAMS ((char const *, size_t)); - size_t (*execute) PARAMS ((char const *, size_t, size_t *, int)); -} const matchers[]; - -/* Exported from fgrepmat.c, egrepmat.c, grepmat.c. */ -extern char const *matcher; - -/* The following flags are exported from grep for the matchers - to look at. */ -extern int match_icase; /* -i */ -extern int match_words; /* -w */ -extern int match_lines; /* -x */ -extern unsigned char eolbyte; /* -z */ Index: gnu/usr.bin/grep/grep.1 =================================================================== --- gnu/usr.bin/grep/grep.1 +++ /dev/null @@ -1,780 +0,0 @@ -.\" grep man page -.\" $FreeBSD$ -.if !\n(.g \{\ -. if !\w|\*(lq| \{\ -. ds lq `` -. if \w'\(lq' .ds lq "\(lq -. \} -. if !\w|\*(rq| \{\ -. ds rq '' -. if \w'\(rq' .ds rq "\(rq -. \} -.\} -.de Id -.ds Dt \\$4 -.. -.Id $Id: grep.1,v 1.23 2002/01/22 13:20:04 bero Exp $ -.TH GREP 1 \*(Dt "GNU Project" -.SH NAME -grep, egrep, fgrep, zgrep, zegrep, zfgrep, -bzgrep, bzegrep, bzfgrep \- print lines matching a pattern -.SH SYNOPSIS -.B grep -.RI [ options ] -.I PATTERN -.RI [ FILE .\|.\|.] -.br -.B grep -.RI [ options ] -.RB [ \-e -.I PATTERN -| -.B \-f -.IR FILE ] -.RI [ FILE .\|.\|.] -.SH DESCRIPTION -.B grep -searches the named input -.IR FILE s -(or standard input if no files are named, or -the file name -.B \- -is given) -for lines containing a match to the given -.IR PATTERN . -By default, -.B grep -prints the matching lines. -.PP -In addition, two variant programs -.B egrep -and -.B fgrep -are available. -.B egrep -is the same as -.BR "grep\ \-E" . -.B fgrep -is the same as -.BR "grep\ \-F" . -.B zgrep -is the same as -.BR "grep\ \-Z" . -.B zegrep -is the same as -.BR "grep\ \-EZ" . -.B zfgrep -is the same as -.BR "grep\ \-FZ" . -.SH OPTIONS -.TP -.BI \-A " NUM" "\fR,\fP \-\^\-after-context=" NUM -Print -.I NUM -lines of trailing context after matching lines. -Places a line containing -.B \-\^\- -between contiguous groups of matches. -.TP -.BR \-a ", " \-\^\-text -Process a binary file as if it were text; this is equivalent to the -.B \-\^\-binary-files=text -option. -.TP -.BI \-B " NUM" "\fR,\fP \-\^\-before-context=" NUM -Print -.I NUM -lines of leading context before matching lines. -Places a line containing -.B \-\^\- -between contiguous groups of matches. -.TP -.BI \-C " NUM" "\fR,\fP \-\^\-context=" NUM -Print -.I NUM -lines of output context. -Places a line containing -.B \-\^\- -between contiguous groups of matches. -.TP -.BR \-b ", " \-\^\-byte-offset -Print the byte offset within the input file before -each line of output. -.TP -.BI \-\^\-binary-files= TYPE -If the first few bytes of a file indicate that the file contains binary -data, assume that the file is of type -.IR TYPE . -By default, -.I TYPE -is -.BR binary , -and -.B grep -normally outputs either -a one-line message saying that a binary file matches, or no message if -there is no match. -If -.I TYPE -is -.BR without-match , -.B grep -assumes that a binary file does not match; this is equivalent to the -.B \-I -option. -If -.I TYPE -is -.BR text , -.B grep -processes a binary file as if it were text; this is equivalent to the -.B \-a -option. -.I Warning: -.B "grep \-\^\-binary-files=text" -might output binary garbage, -which can have nasty side effects if the output is a terminal and if the -terminal driver interprets some of it as commands. -.TP -.BI \-\^\-colour[=\fIWHEN\fR] ", " \-\^\-color[=\fIWHEN\fR] -Surround the matching string with the marker find in -.B GREP_COLOR -environment variable. WHEN may be `never', `always', or `auto' -.TP -.BR \-c ", " \-\^\-count -Suppress normal output; instead print a count of -matching lines for each input file. -With the -.BR \-v ", " \-\^\-invert-match -option (see below), count non-matching lines. -.TP -.BI \-D " ACTION" "\fR,\fP \-\^\-devices=" ACTION -If an input file is a device, FIFO or socket, use -.I ACTION -to process it. By default, -.I ACTION -is -.BR read , -which means that devices are read just as if they were ordinary files. -If -.I ACTION -is -.BR skip , -devices are silently skipped. -.TP -.BI \-d " ACTION" "\fR,\fP \-\^\-directories=" ACTION -If an input file is a directory, use -.I ACTION -to process it. By default, -.I ACTION -is -.BR read , -which means that directories are read just as if they were ordinary files. -If -.I ACTION -is -.BR skip , -directories are silently skipped. -If -.I ACTION -is -.BR recurse , -.B grep -reads all files under each directory, recursively; -this is equivalent to the -.B \-r -option. -.TP -.BR \-E ", " \-\^\-extended-regexp -Interpret -.I PATTERN -as an extended regular expression (see below). -.TP -.BI \-e " PATTERN" "\fR,\fP \-\^\-regexp=" PATTERN -Use -.I PATTERN -as the pattern; useful to protect patterns beginning with -.BR \- . -.TP -.BR \-F ", " \-\^\-fixed-strings -Interpret -.I PATTERN -as a list of fixed strings, separated by newlines, -any of which is to be matched. -.TP -.BR \-P ", " \-\^\-perl-regexp -Interpret -.I PATTERN -as a Perl regular expression. -This option is not supported in FreeBSD. -.TP -.BI \-f " FILE" "\fR,\fP \-\^\-file=" FILE -Obtain patterns from -.IR FILE , -one per line. -The empty file contains zero patterns, and therefore matches nothing. -.TP -.BR \-G ", " \-\^\-basic-regexp -Interpret -.I PATTERN -as a basic regular expression (see below). This is the default. -.TP -.BR \-H ", " \-\^\-with-filename -Print the filename for each match. -.TP -.BR \-h ", " \-\^\-no-filename -Suppress the prefixing of filenames on output -when multiple files are searched. -.TP -.B \-\^\-help -Output a brief help message. -.TP -.BR \-I -Process a binary file as if it did not contain matching data; this is -equivalent to the -.B \-\^\-binary-files=without-match -option. -.TP -.BR \-i ", " \-\^\-ignore-case -Ignore case distinctions in both the -.I PATTERN -and the input files. -.TP -.BR \-L ", " \-\^\-files-without-match -Suppress normal output; instead print the name -of each input file from which no output would -normally have been printed. The scanning will stop -on the first match. -.TP -.BR \-l ", " \-\^\-files-with-matches -Suppress normal output; instead print -the name of each input file from which output -would normally have been printed. The scanning will -stop on the first match. -.TP -.BI \-m " NUM" "\fR,\fP \-\^\-max-count=" NUM -Stop reading a file after -.I NUM -matching lines. If the input is standard input from a regular file, -and -.I NUM -matching lines are output, -.B grep -ensures that the standard input is positioned to just after the last -matching line before exiting, regardless of the presence of trailing -context lines. This enables a calling process to resume a search. -When -.B grep -stops after -.I NUM -matching lines, it outputs any trailing context lines. When the -.B \-c -or -.B \-\^\-count -option is also used, -.B grep -does not output a count greater than -.IR NUM . -When the -.B \-v -or -.B \-\^\-invert-match -option is also used, -.B grep -stops after outputting -.I NUM -non-matching lines. -.TP -.B \-\^\-mmap -If possible, use the -.BR mmap (2) -system call to read input, instead of -the default -.BR read (2) -system call. In some situations, -.B \-\^\-mmap -yields better performance. However, -.B \-\^\-mmap -can cause undefined behavior (including core dumps) -if an input file shrinks while -.B grep -is operating, or if an I/O error occurs. -.TP -.BR \-n ", " \-\^\-line-number -Prefix each line of output with the line number -within its input file. -.TP -.BR \-o ", " \-\^\-only-matching -Show only the part of a matching line that matches -.I PATTERN. -.TP -.BI \-\^\-label= LABEL -Displays input actually coming from standard input as input coming from file -.I LABEL. -This is especially useful for tools like zgrep, e.g. -.B "gzip -cd foo.gz |grep --label=foo something" -.TP -.BR \-\^\-line-buffered -Flush output on every line. -Note that this incurs a performance penalty. -.TP -.BR \-q ", " \-\^\-quiet ", " \-\^\-silent -Quiet; do not write anything to standard output. -Exit immediately with zero status if any match is found, -even if an error was detected. -Also see the -.B \-s -or -.B \-\^\-no-messages -option. -.TP -.BR \-R ", " \-r ", " \-\^\-recursive -Read all files under each directory, recursively; -this is equivalent to the -.B "\-d recurse" -option. -.TP -.BR "\fR \fP \-\^\-include=" PATTERN -Recurse in directories only searching file matching -.I PATTERN. -.TP -.BR "\fR \fP \-\^\-exclude=" PATTERN -Recurse in directories skip file matching -.I PATTERN. -.TP -.BR \-s ", " \-\^\-no-messages -Suppress error messages about nonexistent or unreadable files. -Portability note: unlike \s-1GNU\s0 -.BR grep , -traditional -.B grep -did not conform to \s-1POSIX.2\s0, because traditional -.B grep -lacked a -.B \-q -option and its -.B \-s -option behaved like \s-1GNU\s0 -.BR grep 's -.B \-q -option. -Shell scripts intended to be portable to traditional -.B grep -should avoid both -.B \-q -and -.B \-s -and should redirect output to /dev/null instead. -.TP -.BR \-U ", " \-\^\-binary -Treat the file(s) as binary. By default, under MS-DOS and MS-Windows, -.BR grep -guesses the file type by looking at the contents of the first 32KB -read from the file. If -.BR grep -decides the file is a text file, it strips the CR characters from the -original file contents (to make regular expressions with -.B ^ -and -.B $ -work correctly). Specifying -.B \-U -overrules this guesswork, causing all files to be read and passed to the -matching mechanism verbatim; if the file is a text file with CR/LF -pairs at the end of each line, this will cause some regular -expressions to fail. -This option has no effect on platforms other than MS-DOS and -MS-Windows. -.TP -.BR \-u ", " \-\^\-unix-byte-offsets -Report Unix-style byte offsets. This switch causes -.B grep -to report byte offsets as if the file were Unix-style text file, i.e. with -CR characters stripped off. This will produce results identical to running -.B grep -on a Unix machine. This option has no effect unless -.B \-b -option is also used; -it has no effect on platforms other than MS-DOS and MS-Windows. -.TP -.BR \-V ", " \-\^\-version -Print the version number of -.B grep -to standard error. This version number should -be included in all bug reports (see below). -.TP -.BR \-v ", " \-\^\-invert-match -Invert the sense of matching, to select non-matching lines. -.TP -.BR \-w ", " \-\^\-word-regexp -Select only those lines containing matches that form whole words. -The test is that the matching substring must either be at the -beginning of the line, or preceded by a non-word constituent -character. Similarly, it must be either at the end of the line -or followed by a non-word constituent character. Word-constituent -characters are letters, digits, and the underscore. -.TP -.BR \-x ", " \-\^\-line-regexp -Select only those matches that exactly match the whole line. -.TP -.B \-y -Obsolete synonym for -.BR \-i . -.TP -.B \-\^\-null -Output a zero byte (the \s-1ASCII\s0 -.B NUL -character) instead of the character that normally follows a file name. -For example, -.B "grep \-l \-\^\-null" -outputs a zero byte after each file name instead of the usual newline. -This option makes the output unambiguous, even in the presence of file -names containing unusual characters like newlines. This option can be -used with commands like -.BR "find \-print0" , -.BR "perl \-0" , -.BR "sort \-z" , -and -.B "xargs \-0" -to process arbitrary file names, -even those that contain newline characters. -.TP -.BR \-Z ", " \-\^\-decompress -Decompress the input data before searching. -This option is only available if compiled with -.BR zlib (3) -library. -.TP -.BR \-J ", " \-\^\-bz2decompress -Decompress the -.BR bzip2 (1) -compressed input data before searching. -.SH "REGULAR EXPRESSIONS" -A regular expression is a pattern that describes a set of strings. -Regular expressions are constructed analogously to arithmetic -expressions, by using various operators to combine smaller expressions. -.PP -.B grep -understands two different versions of regular expression syntax: -\*(lqbasic\*(rq and \*(lqextended.\*(rq In -.RB "\s-1GNU\s0\ " grep , -there is no difference in available functionality using either syntax. -In other implementations, basic regular expressions are less powerful. -The following description applies to extended regular expressions; -differences for basic regular expressions are summarized afterwards. -.PP -The fundamental building blocks are the regular expressions that match -a single character. Most characters, including all letters and digits, -are regular expressions that match themselves. Any metacharacter with -special meaning may be quoted by preceding it with a backslash. -.PP -A -.I "bracket expression" -is a list of characters enclosed by -.B [ -and -.BR ] . -It matches any single -character in that list; if the first character of the list -is the caret -.B ^ -then it matches any character -.I not -in the list. -For example, the regular expression -.B [0123456789] -matches any single digit. -.PP -Within a bracket expression, a -.I "range expression" -consists of two characters separated by a hyphen. -It matches any single character that sorts between the two characters, -inclusive, using the locale's collating sequence and character set. -For example, in the default C locale, -.B [a\-d] -is equivalent to -.BR [abcd] . -Many locales sort characters in dictionary order, and in these locales -.B [a\-d] -is typically not equivalent to -.BR [abcd] ; -it might be equivalent to -.BR [aBbCcDd] , -for example. -To obtain the traditional interpretation of bracket expressions, -you can use the C locale by setting the -.B LC_ALL -environment variable to the value -.BR C . -.PP -Finally, certain named classes of characters are predefined within -bracket expressions, as follows. -Their names are self explanatory, and they are -.BR [:alnum:] , -.BR [:alpha:] , -.BR [:blank:] , -.BR [:cntrl:] , -.BR [:digit:] , -.BR [:graph:] , -.BR [:lower:] , -.BR [:print:] , -.BR [:punct:] , -.BR [:space:] , -.BR [:upper:] , -and -.BR [:xdigit:]. -For example, -.B [[:alnum:]] -means -.BR [0\-9A\-Za\-z] , -except the latter form depends upon the C locale and the -\s-1ASCII\s0 character encoding, whereas the former is independent -of locale and character set. -(Note that the brackets in these class names are part of the symbolic -names, and must be included in addition to the brackets delimiting -the bracket list.) Most metacharacters lose their special meaning -inside lists. To include a literal -.B ] -place it first in the list. Similarly, to include a literal -.B ^ -place it anywhere but first. Finally, to include a literal -.B \- -place it last. -.PP -The period -.B . -matches any single character. -The symbol -.B \ew -is a synonym for -.B [[:alnum:]] -and -.B \eW -is a synonym for -.BR [^[:alnum:]] . -.PP -The caret -.B ^ -and the dollar sign -.B $ -are metacharacters that respectively match the empty string at the -beginning and end of a line. -The symbols -.B \e< -and -.B \e> -respectively match the empty string at the beginning and end of a word. -The symbol -.B \eb -matches the empty string at the edge of a word, -and -.B \eB -matches the empty string provided it's -.I not -at the edge of a word. -.PP -A regular expression may be followed by one of several repetition operators: -.PD 0 -.TP -.B ? -The preceding item is optional and matched at most once. -.TP -.B * -The preceding item will be matched zero or more times. -.TP -.B + -The preceding item will be matched one or more times. -.TP -.BI { n } -The preceding item is matched exactly -.I n -times. -.TP -.BI { n ,} -The preceding item is matched -.I n -or more times. -.TP -.BI { n , m } -The preceding item is matched at least -.I n -times, but not more than -.I m -times. -.PD -.PP -Two regular expressions may be concatenated; the resulting -regular expression matches any string formed by concatenating -two substrings that respectively match the concatenated -subexpressions. -.PP -Two regular expressions may be joined by the infix operator -.BR | ; -the resulting regular expression matches any string matching -either subexpression. -.PP -Repetition takes precedence over concatenation, which in turn -takes precedence over alternation. A whole subexpression may be -enclosed in parentheses to override these precedence rules. -.PP -The backreference -.BI \e n\c -\&, where -.I n -is a single digit, matches the substring -previously matched by the -.IR n th -parenthesized subexpression of the regular expression. -.PP -In basic regular expressions the metacharacters -.BR ? , -.BR + , -.BR { , -.BR | , -.BR ( , -and -.BR ) -lose their special meaning; instead use the backslashed -versions -.BR \e? , -.BR \e+ , -.BR \e{ , -.BR \e| , -.BR \e( , -and -.BR \e) . -.PP -Traditional -.B egrep -did not support the -.B { -metacharacter, and some -.B egrep -implementations support -.B \e{ -instead, so portable scripts should avoid -.B { -in -.B egrep -patterns and should use -.B [{] -to match a literal -.BR { . -.PP -\s-1GNU\s0 -.B egrep -attempts to support traditional usage by assuming that -.B { -is not special if it would be the start of an invalid interval -specification. For example, the shell command -.B "egrep '{1'" -searches for the two-character string -.B {1 -instead of reporting a syntax error in the regular expression. -\s-1POSIX.2\s0 allows this behavior as an extension, but portable scripts -should avoid it. -.SH "ENVIRONMENT VARIABLES" -Grep's behavior is affected by the following environment variables. -.PP -A locale -.BI LC_ foo -is specified by examining the three environment variables -.BR LC_ALL , -.BR LC_\fIfoo\fP , -.BR LANG , -in that order. -The first of these variables that is set specifies the locale. -For example, if -.B LC_ALL -is not set, but -.B LC_MESSAGES -is set to -.BR pt_BR , -then Brazilian Portuguese is used for the -.B LC_MESSAGES -locale. -The C locale is used if none of these environment variables are set, -or if the locale catalog is not installed, or if -.B grep -was not compiled with national language support (\s-1NLS\s0). -.TP -.B GREP_OPTIONS -This variable specifies default options to be placed in front of any -explicit options. For example, if -.B GREP_OPTIONS -is -.BR "'\-\^\-binary-files=without-match \-\^\-directories=skip'" , -.B grep -behaves as if the two options -.B \-\^\-binary-files=without-match -and -.B \-\^\-directories=skip -had been specified before any explicit options. -Option specifications are separated by whitespace. -A backslash escapes the next character, -so it can be used to specify an option containing whitespace or a backslash. -.TP -.B GREP_COLOR -Specifies the marker for highlighting. -.TP -\fBLC_ALL\fP, \fBLC_COLLATE\fP, \fBLANG\fP -These variables specify the -.B LC_COLLATE -locale, which determines the collating sequence used to interpret -range expressions like -.BR [a\-z] . -.TP -\fBLC_ALL\fP, \fBLC_CTYPE\fP, \fBLANG\fP -These variables specify the -.B LC_CTYPE -locale, which determines the type of characters, e.g., which -characters are whitespace. -.TP -\fBLC_ALL\fP, \fBLC_MESSAGES\fP, \fBLANG\fP -These variables specify the -.B LC_MESSAGES -locale, which determines the language that -.B grep -uses for messages. -The default C locale uses American English messages. -.TP -.B POSIXLY_CORRECT -If set, -.B grep -behaves as \s-1POSIX.2\s0 requires; otherwise, -.B grep -behaves more like other \s-1GNU\s0 programs. -\s-1POSIX.2\s0 requires that options that follow file names must be -treated as file names; by default, such options are permuted to the -front of the operand list and are treated as options. -Also, \s-1POSIX.2\s0 requires that unrecognized options be diagnosed as -\*(lqillegal\*(rq, but since they are not really against the law the default -is to diagnose them as \*(lqinvalid\*(rq. -.SH DIAGNOSTICS -.PP -Normally, exit status is 0 if selected lines are found and 1 otherwise. -But the exit status is 2 if an error occurred, unless the -.B \-q -or -.B \-\^\-quiet -or -.B \-\^\-silent -option is used and a selected line is found. -.SH BUGS -Email bug reports to -.BR bug-gnu-utils@gnu.org . -Be sure to include the word \*(lqgrep\*(rq somewhere in the -\*(lqSubject:\*(rq field. -.PP -Large repetition counts in the -.BI { n , m } -construct may cause grep to use lots of memory. -In addition, -certain other obscure regular expressions require exponential time -and space, and may cause -.B grep -to run out of memory. -.PP -Backreferences are very slow, and may require exponential time. -.\" Work around problems with some troff -man implementations. -.br Index: gnu/usr.bin/grep/grep.c =================================================================== --- gnu/usr.bin/grep/grep.c +++ /dev/null @@ -1,1867 +0,0 @@ -/* grep.c - main driver file for grep. - Copyright 1992, 1997-1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* Written July 1992 by Mike Haertel. */ -/* Builtin decompression 1997 by Wolfram Schneider . */ - -/* $FreeBSD$ */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#if defined(HAVE_MMAP) -# include -#endif -#if defined(HAVE_SETRLIMIT) -# include -# include -#endif -#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC -/* We can handle multibyte string. */ -# define MBS_SUPPORT -# include -# include -#endif -#include -#include "system.h" -#include "getopt.h" -#include "getpagesize.h" -#include "grep.h" -#include "savedir.h" -#include "xstrtol.h" -#include "xalloc.h" -#include "error.h" -#include "exclude.h" -#include "closeout.h" - -#undef MAX -#define MAX(A,B) ((A) > (B) ? (A) : (B)) - -struct stats -{ - struct stats const *parent; - struct stat stat; -}; - -/* base of chain of stat buffers, used to detect directory loops */ -static struct stats stats_base; - -/* if non-zero, display usage information and exit */ -static int show_help; - -/* If non-zero, print the version on standard output and exit. */ -static int show_version; - -/* If nonzero, suppress diagnostics for nonexistent or unreadable files. */ -static int suppress_errors; - -/* If nonzero, use mmap if possible. */ -static int mmap_option; - -/* If zero, output nulls after filenames. */ -static int filename_mask; - -/* If nonzero, use grep_color marker. */ -static int color_option; - -/* If nonzero, show only the part of a line matching the expression. */ -static int only_matching; - -/* The color string used. The user can overwrite it using the environment - variable GREP_COLOR. The default is to print red. */ -static const char *grep_color = "01;31"; - -static struct exclude *excluded_patterns; -static struct exclude *included_patterns; -/* Short options. */ -static char const short_options[] = -"0123456789A:B:C:D:EFGHIJPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz"; - -/* Non-boolean long options that have no corresponding short equivalents. */ -enum -{ - BINARY_FILES_OPTION = CHAR_MAX + 1, - COLOR_OPTION, - INCLUDE_OPTION, - EXCLUDE_OPTION, - EXCLUDE_FROM_OPTION, - LINE_BUFFERED_OPTION, - LABEL_OPTION -}; - -/* Long options equivalences. */ -static struct option const long_options[] = -{ - {"after-context", required_argument, NULL, 'A'}, - {"basic-regexp", no_argument, NULL, 'G'}, - {"before-context", required_argument, NULL, 'B'}, - {"binary-files", required_argument, NULL, BINARY_FILES_OPTION}, - {"byte-offset", no_argument, NULL, 'b'}, - {"context", required_argument, NULL, 'C'}, - {"color", optional_argument, NULL, COLOR_OPTION}, - {"colour", optional_argument, NULL, COLOR_OPTION}, - {"count", no_argument, NULL, 'c'}, - {"devices", required_argument, NULL, 'D'}, - {"directories", required_argument, NULL, 'd'}, - {"extended-regexp", no_argument, NULL, 'E'}, - {"exclude", required_argument, NULL, EXCLUDE_OPTION}, - {"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION}, - {"file", required_argument, NULL, 'f'}, - {"files-with-matches", no_argument, NULL, 'l'}, - {"files-without-match", no_argument, NULL, 'L'}, - {"fixed-regexp", no_argument, NULL, 'F'}, - {"fixed-strings", no_argument, NULL, 'F'}, - {"help", no_argument, &show_help, 1}, - {"include", required_argument, NULL, INCLUDE_OPTION}, - {"ignore-case", no_argument, NULL, 'i'}, - {"label", required_argument, NULL, LABEL_OPTION}, - {"line-buffered", no_argument, NULL, LINE_BUFFERED_OPTION}, - {"line-number", no_argument, NULL, 'n'}, - {"line-regexp", no_argument, NULL, 'x'}, - {"max-count", required_argument, NULL, 'm'}, - {"mmap", no_argument, &mmap_option, 1}, - {"no-filename", no_argument, NULL, 'h'}, - {"no-messages", no_argument, NULL, 's'}, - {"bz2decompress", no_argument, NULL, 'J'}, -#if HAVE_LIBZ > 0 - {"decompress", no_argument, NULL, 'Z'}, - {"null", no_argument, &filename_mask, 0}, -#else - {"null", no_argument, NULL, 'Z'}, -#endif - {"null-data", no_argument, NULL, 'z'}, - {"only-matching", no_argument, NULL, 'o'}, - {"perl-regexp", no_argument, NULL, 'P'}, - {"quiet", no_argument, NULL, 'q'}, - {"recursive", no_argument, NULL, 'r'}, - {"recursive", no_argument, NULL, 'R'}, - {"regexp", required_argument, NULL, 'e'}, - {"invert-match", no_argument, NULL, 'v'}, - {"silent", no_argument, NULL, 'q'}, - {"text", no_argument, NULL, 'a'}, - {"binary", no_argument, NULL, 'U'}, - {"unix-byte-offsets", no_argument, NULL, 'u'}, - {"version", no_argument, NULL, 'V'}, - {"with-filename", no_argument, NULL, 'H'}, - {"word-regexp", no_argument, NULL, 'w'}, - {0, 0, 0, 0} -}; - -/* Define flags declared in grep.h. */ -int match_icase; -int match_words; -int match_lines; -unsigned char eolbyte; - -/* For error messages. */ -/* The name the program was run with, stripped of any leading path. */ -char *program_name; -static char const *filename; -static int errseen; - -/* How to handle directories. */ -static enum - { - READ_DIRECTORIES, - RECURSE_DIRECTORIES, - SKIP_DIRECTORIES - } directories = READ_DIRECTORIES; - -/* How to handle devices. */ -static enum - { - READ_DEVICES, - SKIP_DEVICES - } devices = READ_DEVICES; - -static int grepdir PARAMS ((char const *, struct stats const *)); -#if defined(HAVE_DOS_FILE_CONTENTS) -static inline int undossify_input PARAMS ((register char *, size_t)); -#endif - -/* Functions we'll use to search. */ -static void (*compile) PARAMS ((char const *, size_t)); -static size_t (*execute) PARAMS ((char const *, size_t, size_t *, int)); - -/* Like error, but suppress the diagnostic if requested. */ -static void -suppressible_error (char const *mesg, int errnum) -{ - if (! suppress_errors) - error (0, errnum, "%s", mesg); - errseen = 1; -} - -/* Convert STR to a positive integer, storing the result in *OUT. - STR must be a valid context length argument; report an error if it - isn't. */ -static void -context_length_arg (char const *str, int *out) -{ - uintmax_t value; - if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK - && 0 <= (*out = value) - && *out == value)) - { - error (2, 0, "%s: %s\n", str, _("invalid context length argument")); - } -} - - -/* Hairy buffering mechanism for grep. The intent is to keep - all reads aligned on a page boundary and multiples of the - page size, unless a read yields a partial page. */ - -static char *buffer; /* Base of buffer. */ -static size_t bufalloc; /* Allocated buffer size, counting slop. */ -#define INITIAL_BUFSIZE 32768 /* Initial buffer size, not counting slop. */ -static int bufdesc; /* File descriptor. */ -static char *bufbeg; /* Beginning of user-visible stuff. */ -static char *buflim; /* Limit of user-visible stuff. */ -static size_t pagesize; /* alignment of memory pages */ -static off_t bufoffset; /* Read offset; defined on regular files. */ -static off_t after_last_match; /* Pointer after last matching line that - would have been output if we were - outputting characters. */ - -#if defined(HAVE_MMAP) -static int bufmapped; /* True if buffer is memory-mapped. */ -static off_t initial_bufoffset; /* Initial value of bufoffset. */ -#else -# define bufmapped 0 -#endif - -#include -static BZFILE* bzbufdesc; /* libbz2 file handle. */ -static int BZflag; /* uncompress before searching. */ -#if HAVE_LIBZ > 0 -#include -static gzFile gzbufdesc; /* zlib file descriptor. */ -static int Zflag; /* uncompress before searching. */ -#endif - -/* Return VAL aligned to the next multiple of ALIGNMENT. VAL can be - an integer or a pointer. Both args must be free of side effects. */ -#define ALIGN_TO(val, alignment) \ - ((size_t) (val) % (alignment) == 0 \ - ? (val) \ - : (val) + ((alignment) - (size_t) (val) % (alignment))) - -/* Reset the buffer for a new file, returning zero if we should skip it. - Initialize on the first time through. */ -static int -reset (int fd, char const *file, struct stats *stats) -{ - if (! pagesize) - { - pagesize = getpagesize (); - if (pagesize == 0 || 2 * pagesize + 1 <= pagesize) - abort (); - bufalloc = ALIGN_TO (INITIAL_BUFSIZE, pagesize) + pagesize + 1; - buffer = xmalloc (bufalloc); - } - if (BZflag) - { - bzbufdesc = BZ2_bzdopen(fd, "r"); - if (bzbufdesc == NULL) - error(2, 0, _("memory exhausted")); - } -#if HAVE_LIBZ > 0 - if (Zflag) - { - gzbufdesc = gzdopen(fd, "r"); - if (gzbufdesc == NULL) - error(2, 0, _("memory exhausted")); - } -#endif - - bufbeg = buflim = ALIGN_TO (buffer + 1, pagesize); - bufbeg[-1] = eolbyte; - bufdesc = fd; - - if (fstat (fd, &stats->stat) != 0) - { - error (0, errno, "fstat"); - return 0; - } - if (fd != STDIN_FILENO) { - if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode)) - return 0; -#ifndef DJGPP - if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode))) -#else - if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode))) -#endif - return 0; - } - if ( - BZflag || -#if HAVE_LIBZ > 0 - Zflag || -#endif - S_ISREG (stats->stat.st_mode)) - { - if (file) - bufoffset = 0; - else - { - bufoffset = lseek (fd, 0, SEEK_CUR); - if (bufoffset < 0) - { - error (0, errno, "lseek"); - return 0; - } - } -#if defined(HAVE_MMAP) - initial_bufoffset = bufoffset; - bufmapped = mmap_option && bufoffset % pagesize == 0; -#endif - } - else - { -#if defined(HAVE_MMAP) - bufmapped = 0; -#endif - } - return 1; -} - -/* Read new stuff into the buffer, saving the specified - amount of old stuff. When we're done, 'bufbeg' points - to the beginning of the buffer contents, and 'buflim' - points just after the end. Return zero if there's an error. */ -static int -fillbuf (size_t save, struct stats const *stats) -{ - size_t fillsize = 0; - int cc = 1; - char *readbuf; - size_t readsize; - - /* Offset from start of buffer to start of old stuff - that we want to save. */ - size_t saved_offset = buflim - save - buffer; - - if (pagesize <= buffer + bufalloc - buflim) - { - readbuf = buflim; - bufbeg = buflim - save; - } - else - { - size_t minsize = save + pagesize; - size_t newsize; - size_t newalloc; - char *newbuf; - - /* Grow newsize until it is at least as great as minsize. */ - for (newsize = bufalloc - pagesize - 1; newsize < minsize; newsize *= 2) - if (newsize * 2 < newsize || newsize * 2 + pagesize + 1 < newsize * 2) - xalloc_die (); - - /* Try not to allocate more memory than the file size indicates, - as that might cause unnecessary memory exhaustion if the file - is large. However, do not use the original file size as a - heuristic if we've already read past the file end, as most - likely the file is growing. */ - if (S_ISREG (stats->stat.st_mode)) - { - off_t to_be_read = stats->stat.st_size - bufoffset; - off_t maxsize_off = save + to_be_read; - if (0 <= to_be_read && to_be_read <= maxsize_off - && maxsize_off == (size_t) maxsize_off - && minsize <= (size_t) maxsize_off - && (size_t) maxsize_off < newsize) - newsize = maxsize_off; - } - - /* Add enough room so that the buffer is aligned and has room - for byte sentinels fore and aft. */ - newalloc = newsize + pagesize + 1; - - newbuf = bufalloc < newalloc ? xmalloc (bufalloc = newalloc) : buffer; - readbuf = ALIGN_TO (newbuf + 1 + save, pagesize); - bufbeg = readbuf - save; - memmove (bufbeg, buffer + saved_offset, save); - bufbeg[-1] = eolbyte; - if (newbuf != buffer) - { - free (buffer); - buffer = newbuf; - } - } - - readsize = buffer + bufalloc - readbuf; - readsize -= readsize % pagesize; - -#if defined(HAVE_MMAP) - if (bufmapped) - { - size_t mmapsize = readsize; - - /* Don't mmap past the end of the file; some hosts don't allow this. - Use `read' on the last page. */ - if (stats->stat.st_size - bufoffset < mmapsize) - { - mmapsize = stats->stat.st_size - bufoffset; - mmapsize -= mmapsize % pagesize; - } - - if (mmapsize - && (mmap ((caddr_t) readbuf, mmapsize, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, - bufdesc, bufoffset) - != (caddr_t) -1)) - { - /* Do not bother to use madvise with MADV_SEQUENTIAL or - MADV_WILLNEED on the mmapped memory. One might think it - would help, but it slows us down about 30% on SunOS 4.1. */ - fillsize = mmapsize; - } - else - { - /* Stop using mmap on this file. Synchronize the file - offset. Do not warn about mmap failures. On some hosts - (e.g. Solaris 2.5) mmap can fail merely because some - other process has an advisory read lock on the file. - There's no point alarming the user about this misfeature. */ - bufmapped = 0; - if (bufoffset != initial_bufoffset - && lseek (bufdesc, bufoffset, SEEK_SET) < 0) - { - error (0, errno, "lseek"); - cc = 0; - } - } - } -#endif /*HAVE_MMAP*/ - - if (! fillsize) - { - ssize_t bytesread; - do - if (BZflag && bzbufdesc) - { - int bzerr; - bytesread = BZ2_bzRead (&bzerr, bzbufdesc, readbuf, readsize); - - switch (bzerr) - { - case BZ_OK: - case BZ_STREAM_END: - /* ok */ - break; - case BZ_DATA_ERROR_MAGIC: - BZ2_bzReadClose (&bzerr, bzbufdesc); bzbufdesc = NULL; - lseek (bufdesc, 0, SEEK_SET); - bytesread = read (bufdesc, readbuf, readsize); - break; - default: - bytesread = 0; - break; - } - } - else -#if HAVE_LIBZ > 0 - if (Zflag) - bytesread = gzread (gzbufdesc, readbuf, readsize); - else -#endif - bytesread = read (bufdesc, readbuf, readsize); - while (bytesread < 0 && errno == EINTR); - if (bytesread < 0) - cc = 0; - else - fillsize = bytesread; - } - - bufoffset += fillsize; -#if defined(HAVE_DOS_FILE_CONTENTS) - if (fillsize) - fillsize = undossify_input (readbuf, fillsize); -#endif - buflim = readbuf + fillsize; - return cc; -} - -/* Flags controlling the style of output. */ -static enum -{ - BINARY_BINARY_FILES, - TEXT_BINARY_FILES, - WITHOUT_MATCH_BINARY_FILES -} binary_files; /* How to handle binary files. */ - -static int filename_mask; /* If zero, output nulls after filenames. */ -static int out_quiet; /* Suppress all normal output. */ -static int out_invert; /* Print nonmatching stuff. */ -static int out_file; /* Print filenames. */ -static int out_line; /* Print line numbers. */ -static int out_byte; /* Print byte offsets. */ -static int out_before; /* Lines of leading context. */ -static int out_after; /* Lines of trailing context. */ -static int count_matches; /* Count matching lines. */ -static int list_files; /* List matching files. */ -static int no_filenames; /* Suppress file names. */ -static off_t max_count; /* Stop after outputting this many - lines from an input file. */ -static int line_buffered; /* If nonzero, use line buffering, i.e. - fflush everyline out. */ -static char *label = NULL; /* Fake filename for stdin */ - - -/* Internal variables to keep track of byte count, context, etc. */ -static uintmax_t totalcc; /* Total character count before bufbeg. */ -static char const *lastnl; /* Pointer after last newline counted. */ -static char const *lastout; /* Pointer after last character output; - NULL if no character has been output - or if it's conceptually before bufbeg. */ -static uintmax_t totalnl; /* Total newline count before lastnl. */ -static off_t outleft; /* Maximum number of lines to be output. */ -static int pending; /* Pending lines of output. - Always kept 0 if out_quiet is true. */ -static int done_on_match; /* Stop scanning file on first match. */ -static int exit_on_match; /* Exit on first match. */ - -#if defined(HAVE_DOS_FILE_CONTENTS) -# include "dosbuf.c" -#endif - -/* Add two numbers that count input bytes or lines, and report an - error if the addition overflows. */ -static uintmax_t -add_count (uintmax_t a, uintmax_t b) -{ - uintmax_t sum = a + b; - if (sum < a) - error (2, 0, _("input is too large to count")); - return sum; -} - -static void -nlscan (char const *lim) -{ - size_t newlines = 0; - char const *beg; - for (beg = lastnl; beg != lim; beg = memchr (beg, eolbyte, lim - beg), beg++) - newlines++; - totalnl = add_count (totalnl, newlines); - lastnl = lim; -} - -/* Print a byte offset, followed by a character separator. */ -static void -print_offset_sep (uintmax_t pos, char sep) -{ - /* Do not rely on printf to print pos, since uintmax_t may be longer - than long, and long long is not portable. */ - - char buf[sizeof pos * CHAR_BIT]; - char *p = buf + sizeof buf - 1; - *p = sep; - - do - *--p = '0' + pos % 10; - while ((pos /= 10) != 0); - - fwrite (p, 1, buf + sizeof buf - p, stdout); -} - -static void -prline (char const *beg, char const *lim, int sep) -{ - if (out_file) - printf ("%s%c", filename, sep & filename_mask); - if (out_line) - { - nlscan (beg); - totalnl = add_count (totalnl, 1); - print_offset_sep (totalnl, sep); - lastnl = lim; - } - if (out_byte) - { - uintmax_t pos = add_count (totalcc, beg - bufbeg); -#if defined(HAVE_DOS_FILE_CONTENTS) - pos = dossified_pos (pos); -#endif - print_offset_sep (pos, sep); - } - if (only_matching) - { - size_t match_size; - size_t match_offset; - while ((match_offset = (*execute) (beg, lim - beg, &match_size, 1)) - != (size_t) -1) - { - char const *b = beg + match_offset; - if (b == lim) - break; - if (match_size == 0) - break; - if(color_option) - printf("\33[%sm", grep_color); - fwrite(b, sizeof (char), match_size, stdout); - if(color_option) - fputs("\33[00m", stdout); - fputs("\n", stdout); - beg = b + match_size; - } - lastout = lim; - if(line_buffered) - fflush(stdout); - return; - } - if (color_option) - { - size_t match_size; - size_t match_offset; - while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1)) - != (size_t) -1) - { - char const *b = beg + match_offset; - /* Avoid matching the empty line at the end of the buffer. */ - if (b == lim) - break; - /* Avoid hanging on grep --color "" foo */ - if (match_size == 0) - break; - fwrite (beg, sizeof (char), match_offset, stdout); - printf ("\33[%sm", grep_color); - fwrite (b, sizeof (char), match_size, stdout); - fputs ("\33[00m", stdout); - beg = b + match_size; - } - fputs ("\33[K", stdout); - } - fwrite (beg, 1, lim - beg, stdout); - if (ferror (stdout)) - error (0, errno, _("writing output")); - lastout = lim; - if (line_buffered) - fflush (stdout); -} - -/* Print pending lines of trailing context prior to LIM. Trailing context ends - at the next matching line when OUTLEFT is 0. */ -static void -prpending (char const *lim) -{ - if (!lastout) - lastout = bufbeg; - while (pending > 0 && lastout < lim) - { - char const *nl = memchr (lastout, eolbyte, lim - lastout); - size_t match_size; - --pending; - if (outleft - || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1) - == !out_invert)) - prline (lastout, nl + 1, '-'); - else - pending = 0; - } -} - -/* Print the lines between BEG and LIM. Deal with context crap. - If NLINESP is non-null, store a count of lines between BEG and LIM. */ -static void -prtext (char const *beg, char const *lim, int *nlinesp) -{ - static int used; /* avoid printing "--" before any output */ - char const *bp, *p; - char eol = eolbyte; - int i, n; - - if (!out_quiet && pending > 0) - prpending (beg); - - p = beg; - - if (!out_quiet) - { - /* Deal with leading context crap. */ - - bp = lastout ? lastout : bufbeg; - for (i = 0; i < out_before; ++i) - if (p > bp) - do - --p; - while (p[-1] != eol); - - /* We only print the "--" separator if our output is - discontiguous from the last output in the file. */ - if ((out_before || out_after) && used && p != lastout) - puts ("--"); - - while (p < beg) - { - char const *nl = memchr (p, eol, beg - p); - nl++; - prline (p, nl, '-'); - p = nl; - } - } - - if (nlinesp) - { - /* Caller wants a line count. */ - for (n = 0; p < lim && n < outleft; n++) - { - char const *nl = memchr (p, eol, lim - p); - nl++; - if (!out_quiet) - prline (p, nl, ':'); - p = nl; - } - *nlinesp = n; - - /* relying on it that this function is never called when outleft = 0. */ - after_last_match = bufoffset - (buflim - p); - } - else - if (!out_quiet) - prline (beg, lim, ':'); - - pending = out_quiet ? 0 : out_after; - used = 1; -} - -/* Scan the specified portion of the buffer, matching lines (or - between matching lines if OUT_INVERT is true). Return a count of - lines printed. */ -static int -grepbuf (char const *beg, char const *lim) -{ - int nlines, n; - register char const *p; - size_t match_offset; - size_t match_size; - - nlines = 0; - p = beg; - while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1) - { - char const *b = p + match_offset; - char const *endp = b + match_size; - /* Avoid matching the empty line at the end of the buffer. */ - if (b == lim) - break; - if (!out_invert) - { - prtext (b, endp, (int *) 0); - nlines++; - outleft--; - if (!outleft || done_on_match) - { - if (exit_on_match) - exit (0); - after_last_match = bufoffset - (buflim - endp); - return nlines; - } - } - else if (p < b) - { - prtext (p, b, &n); - nlines += n; - outleft -= n; - if (!outleft) - return nlines; - } - p = endp; - } - if (out_invert && p < lim) - { - prtext (p, lim, &n); - nlines += n; - outleft -= n; - } - return nlines; -} - -/* Search a given file. Normally, return a count of lines printed; - but if the file is a directory and we search it recursively, then - return -2 if there was a match, and -1 otherwise. */ -static int -grep (int fd, char const *file, struct stats *stats) -{ - int nlines, i; - int not_text; - size_t residue, save; - char oldc; - char *beg; - char *lim; - char eol = eolbyte; - - if (!reset (fd, file, stats)) - return 0; - - if (file && directories == RECURSE_DIRECTORIES - && S_ISDIR (stats->stat.st_mode)) - { - /* Close fd now, so that we don't open a lot of file descriptors - when we recurse deeply. */ - if (BZflag && bzbufdesc) - BZ2_bzclose(bzbufdesc); - else -#if HAVE_LIBZ > 0 - if (Zflag) - gzclose(gzbufdesc); - else -#endif - if (close (fd) != 0) - error (0, errno, "%s", file); - return grepdir (file, stats) - 2; - } - - totalcc = 0; - lastout = 0; - totalnl = 0; - outleft = max_count; - after_last_match = 0; - pending = 0; - - nlines = 0; - residue = 0; - save = 0; - - if (! fillbuf (save, stats)) - { - if (! is_EISDIR (errno, file)) - suppressible_error (filename, errno); - return 0; - } - - not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet) - || binary_files == WITHOUT_MATCH_BINARY_FILES) - && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg)); - if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES) - return 0; - done_on_match += not_text; - out_quiet += not_text; - - for (;;) - { - lastnl = bufbeg; - if (lastout) - lastout = bufbeg; - - beg = bufbeg + save; - - /* no more data to scan (eof) except for maybe a residue -> break */ - if (beg == buflim) - break; - - /* Determine new residue (the length of an incomplete line at the end of - the buffer, 0 means there is no incomplete last line). */ - oldc = beg[-1]; - beg[-1] = eol; - for (lim = buflim; lim[-1] != eol; lim--) - continue; - beg[-1] = oldc; - if (lim == beg) - lim = beg - residue; - beg -= residue; - residue = buflim - lim; - - if (beg < lim) - { - if (outleft) - nlines += grepbuf (beg, lim); - if (pending) - prpending (lim); - if((!outleft && !pending) || (nlines && done_on_match && !out_invert)) - goto finish_grep; - } - - /* The last OUT_BEFORE lines at the end of the buffer will be needed as - leading context if there is a matching line at the begin of the - next data. Make beg point to their begin. */ - i = 0; - beg = lim; - while (i < out_before && beg > bufbeg && beg != lastout) - { - ++i; - do - --beg; - while (beg[-1] != eol); - } - - /* detect if leading context is discontinuous from last printed line. */ - if (beg != lastout) - lastout = 0; - - /* Handle some details and read more data to scan. */ - save = residue + lim - beg; - if (out_byte) - totalcc = add_count (totalcc, buflim - bufbeg - save); - if (out_line) - nlscan (beg); - if (! fillbuf (save, stats)) - { - if (! is_EISDIR (errno, file)) - suppressible_error (filename, errno); - goto finish_grep; - } - } - if (residue) - { - *buflim++ = eol; - if (outleft) - nlines += grepbuf (bufbeg + save - residue, buflim); - if (pending) - prpending (buflim); - } - - finish_grep: - done_on_match -= not_text; - out_quiet -= not_text; - if ((not_text & ~out_quiet) && nlines != 0) - printf (_("Binary file %s matches\n"), filename); - return nlines; -} - -static int -grepfile (char const *file, struct stats *stats) -{ - int desc; - int count; - int status; - int flags; - - if (! file) - { - desc = 0; - filename = label ? label : _("(standard input)"); - } - else - { - while ((desc = open (file, O_RDONLY | O_NONBLOCK)) < 0 && errno == EINTR) - continue; - - if (desc < 0) - { - int e = errno; - - if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES) - { - if (stat (file, &stats->stat) != 0) - { - error (0, errno, "%s", file); - return 1; - } - - return grepdir (file, stats); - } - - if (!suppress_errors) - { - if (directories == SKIP_DIRECTORIES) - switch (e) - { -#if defined(EISDIR) - case EISDIR: - return 1; -#endif - case EACCES: - /* When skipping directories, don't worry about - directories that can't be opened. */ - if (isdir (file)) - return 1; - break; - } - } - - suppressible_error (file, e); - return 1; - } - - flags = fcntl(desc, F_GETFL); - flags &= ~O_NONBLOCK; - fcntl(desc, F_SETFL, flags); - filename = file; - } - -#if defined(SET_BINARY) - /* Set input to binary mode. Pipes are simulated with files - on DOS, so this includes the case of "foo | grep bar". */ - if (!isatty (desc)) - SET_BINARY (desc); -#endif - - count = grep (desc, file, stats); - if (count < 0) - status = count + 2; - else - { - if (count_matches) - { - if (out_file) - printf ("%s%c", filename, ':' & filename_mask); - printf ("%d\n", count); - } - - status = !count; - if (list_files == 1 - 2 * status) - printf ("%s%c", filename, '\n' & filename_mask); - - if (BZflag && bzbufdesc) - BZ2_bzclose(bzbufdesc); - else -#if HAVE_LIBZ > 0 - if (Zflag) - gzclose(gzbufdesc); - else -#endif - if (! file) - { - off_t required_offset = outleft ? bufoffset : after_last_match; - if ((bufmapped || required_offset != bufoffset) - && lseek (desc, required_offset, SEEK_SET) < 0 - && S_ISREG (stats->stat.st_mode)) - error (0, errno, "%s", filename); - } - else - while (close (desc) != 0) - if (errno != EINTR) - { - error (0, errno, "%s", file); - break; - } - } - - return status; -} - -static int -grepdir (char const *dir, struct stats const *stats) -{ - int status = 1; - struct stats const *ancestor; - char *name_space; - - /* Mingw32 does not support st_ino. No known working hosts use zero - for st_ino, so assume that the Mingw32 bug applies if it's zero. */ - if (stats->stat.st_ino) - for (ancestor = stats; (ancestor = ancestor->parent) != 0; ) - if (ancestor->stat.st_ino == stats->stat.st_ino - && ancestor->stat.st_dev == stats->stat.st_dev) - { - if (!suppress_errors) - error (0, 0, _("warning: %s: %s"), dir, - _("recursive directory loop")); - return 1; - } - - name_space = savedir (dir, stats->stat.st_size, included_patterns, - excluded_patterns); - - if (! name_space) - { - if (errno) - suppressible_error (dir, errno); - else - xalloc_die (); - } - else - { - size_t dirlen = strlen (dir); - int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir) - || IS_SLASH (dir[dirlen - 1])); - char *file = NULL; - char const *namep = name_space; - struct stats child; - child.parent = stats; - out_file += !no_filenames; - while (*namep) - { - size_t namelen = strlen (namep); - file = xrealloc (file, dirlen + 1 + namelen + 1); - strcpy (file, dir); - file[dirlen] = '/'; - strcpy (file + dirlen + needs_slash, namep); - namep += namelen + 1; - status &= grepfile (file, &child); - } - out_file -= !no_filenames; - if (file) - free (file); - free (name_space); - } - - return status; -} - -static void -usage (int status) -{ - if (status != 0) - { - fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"), - program_name); - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); - } - else - { - printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name); - printf (_("\ -Search for PATTERN in each FILE or standard input.\n\ -Example: %s -i 'hello world' menu.h main.c\n\ -\n\ -Regexp selection and interpretation:\n"), program_name); - printf (_("\ - -E, --extended-regexp PATTERN is an extended regular expression\n\ - -F, --fixed-strings PATTERN is a set of newline-separated strings\n\ - -G, --basic-regexp PATTERN is a basic regular expression\n\ - -P, --perl-regexp PATTERN is a Perl regular expression\n")); - printf (_("\ - -e, --regexp=PATTERN use PATTERN as a regular expression\n\ - -f, --file=FILE obtain PATTERN from FILE\n\ - -i, --ignore-case ignore case distinctions\n\ - -w, --word-regexp force PATTERN to match only whole words\n\ - -x, --line-regexp force PATTERN to match only whole lines\n\ - -z, --null-data a data line ends in 0 byte, not newline\n")); - printf (_("\ -\n\ -Miscellaneous:\n\ - -s, --no-messages suppress error messages\n\ - -v, --invert-match select non-matching lines\n\ - -V, --version print version information and exit\n\ - --help display this help and exit\n\ - -J, --bz2decompress decompress bzip2'ed input before searching\n\ - -Z, --decompress decompress input before searching (HAVE_LIBZ=1)\n\ - --mmap use memory-mapped input if possible\n")); - printf (_("\ -\n\ -Output control:\n\ - -m, --max-count=NUM stop after NUM matches\n\ - -b, --byte-offset print the byte offset with output lines\n\ - -n, --line-number print line number with output lines\n\ - --line-buffered flush output on every line\n\ - -H, --with-filename print the filename for each match\n\ - -h, --no-filename suppress the prefixing filename on output\n\ - --label=LABEL print LABEL as filename for standard input\n\ - -o, --only-matching show only the part of a line matching PATTERN\n\ - -q, --quiet, --silent suppress all normal output\n\ - --binary-files=TYPE assume that binary files are TYPE\n\ - TYPE is 'binary', 'text', or 'without-match'\n\ - -a, --text equivalent to --binary-files=text\n\ - -I equivalent to --binary-files=without-match\n\ - -d, --directories=ACTION how to handle directories\n\ - ACTION is 'read', 'recurse', or 'skip'\n\ - -D, --devices=ACTION how to handle devices, FIFOs and sockets\n\ - ACTION is 'read' or 'skip'\n\ - -R, -r, --recursive equivalent to --directories=recurse\n\ - --include=PATTERN files that match PATTERN will be examined\n\ - --exclude=PATTERN files that match PATTERN will be skipped.\n\ - --exclude-from=FILE files that match PATTERN in FILE will be skipped.\n\ - -L, --files-without-match only print FILE names containing no match\n\ - -l, --files-with-matches only print FILE names containing matches\n\ - -c, --count only print a count of matching lines per FILE\n\ - --null print 0 byte after FILE name\n")); - printf (_("\ -\n\ -Context control:\n\ - -B, --before-context=NUM print NUM lines of leading context\n\ - -A, --after-context=NUM print NUM lines of trailing context\n\ - -C, --context=NUM print NUM lines of output context\n\ - -NUM same as --context=NUM\n\ - --color[=WHEN],\n\ - --colour[=WHEN] use markers to distinguish the matching string\n\ - WHEN may be `always', `never' or `auto'.\n\ - -U, --binary do not strip CR characters at EOL (MSDOS)\n\ - -u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS)\n\ -\n\ -`egrep' means `grep -E'. `fgrep' means `grep -F'.\n\ -With no FILE, or when FILE is -, read standard input. If less than\n\ -two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\ -and 2 if trouble.\n")); - printf (_("\nReport bugs to .\n")); - } - exit (status); -} - -/* Set the matcher to M, reporting any conflicts. */ -static void -setmatcher (char const *m) -{ - if (matcher && strcmp (matcher, m) != 0) - error (2, 0, _("conflicting matchers specified")); - matcher = m; -} - -/* Go through the matchers vector and look for the specified matcher. - If we find it, install it in compile and execute, and return 1. */ -static int -install_matcher (char const *name) -{ - int i; -#if defined(HAVE_SETRLIMIT) - struct rlimit rlim; -#endif - - for (i = 0; matchers[i].compile; i++) - if (strcmp (name, matchers[i].name) == 0) - { - compile = matchers[i].compile; - execute = matchers[i].execute; -#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) - /* I think every platform needs to do this, so that regex.c - doesn't oveflow the stack. The default value of - `re_max_failures' is too large for some platforms: it needs - more than 3MB-large stack. - - The test for HAVE_SETRLIMIT should go into `configure'. */ - if (!getrlimit (RLIMIT_STACK, &rlim)) - { - long newlim; - extern long int re_max_failures; /* from regex.c */ - - /* Approximate the amount regex.c needs, plus some more. */ - newlim = re_max_failures * 2 * 20 * sizeof (char *); - if (newlim > rlim.rlim_max) - { - newlim = rlim.rlim_max; - re_max_failures = newlim / (2 * 20 * sizeof (char *)); - } - if (rlim.rlim_cur < newlim) - { - rlim.rlim_cur = newlim; - setrlimit (RLIMIT_STACK, &rlim); - } - } -#endif - return 1; - } - return 0; -} - -/* Find the white-space-separated options specified by OPTIONS, and - using BUF to store copies of these options, set ARGV[0], ARGV[1], - etc. to the option copies. Return the number N of options found. - Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0] - etc. Backslash can be used to escape whitespace (and backslashes). */ -static int -prepend_args (char const *options, char *buf, char **argv) -{ - char const *o = options; - char *b = buf; - int n = 0; - - for (;;) - { - while (ISSPACE ((unsigned char) *o)) - o++; - if (!*o) - return n; - if (argv) - argv[n] = b; - n++; - - do - if ((*b++ = *o++) == '\\' && *o) - b[-1] = *o++; - while (*o && ! ISSPACE ((unsigned char) *o)); - - *b++ = '\0'; - } -} - -/* Prepend the whitespace-separated options in OPTIONS to the argument - vector of a main program with argument count *PARGC and argument - vector *PARGV. */ -static void -prepend_default_options (char const *options, int *pargc, char ***pargv) -{ - if (options) - { - char *buf = xmalloc (strlen (options) + 1); - int prepended = prepend_args (options, buf, (char **) NULL); - int argc = *pargc; - char * const *argv = *pargv; - char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp); - *pargc = prepended + argc; - *pargv = pp; - *pp++ = *argv++; - pp += prepend_args (options, buf, pp); - while ((*pp++ = *argv++)) - continue; - } -} - -/* Get the next non-digit option from ARGC and ARGV. - Return -1 if there are no more options. - Process any digit options that were encountered on the way, - and store the resulting integer into *DEFAULT_CONTEXT. */ -static int -get_nondigit_option (int argc, char *const *argv, int *default_context) -{ - int opt; - char buf[sizeof (uintmax_t) * CHAR_BIT + 4]; - char *p = buf; - - /* Set buf[0] to anything but '0', for the leading-zero test below. */ - buf[0] = '\0'; - - while (opt = getopt_long (argc, argv, short_options, long_options, NULL), - '0' <= opt && opt <= '9') - { - /* Suppress trivial leading zeros, to avoid incorrect - diagnostic on strings like 00000000000. */ - p -= buf[0] == '0'; - - *p++ = opt; - if (p == buf + sizeof buf - 4) - { - /* Too many digits. Append "..." to make context_length_arg - complain about "X...", where X contains the digits seen - so far. */ - strcpy (p, "..."); - p += 3; - break; - } - } - if (p != buf) - { - *p = '\0'; - context_length_arg (buf, default_context); - } - - return opt; -} - -int -main (int argc, char **argv) -{ - char *keys; - size_t cc, keycc, oldcc, keyalloc; - int with_filenames; - int opt, status; - int default_context; - FILE *fp; - extern char *optarg; - extern int optind; - - initialize_main (&argc, &argv); - program_name = argv[0]; - if (program_name && strrchr (program_name, '/')) - program_name = strrchr (program_name, '/') + 1; - - if (program_name[0] == 'b' && program_name[1] == 'z') { - BZflag = 1; - program_name += 2; - } -#if HAVE_LIBZ > 0 - else if (program_name[0] == 'z') { - Zflag = 1; - ++program_name; - } -#endif - -#if defined(__MSDOS__) || defined(_WIN32) - /* DOS and MS-Windows use backslashes as directory separators, and usually - have an .exe suffix. They also have case-insensitive filesystems. */ - if (program_name) - { - char *p = program_name; - char *bslash = strrchr (argv[0], '\\'); - - if (bslash && bslash >= program_name) /* for mixed forward/backslash case */ - program_name = bslash + 1; - else if (program_name == argv[0] - && argv[0][0] && argv[0][1] == ':') /* "c:progname" */ - program_name = argv[0] + 2; - - /* Collapse the letter-case, so `strcmp' could be used hence. */ - for ( ; *p; p++) - if (*p >= 'A' && *p <= 'Z') - *p += 'a' - 'A'; - - /* Remove the .exe extension, if any. */ - if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0) - *p = '\0'; - } -#endif - - keys = NULL; - keycc = 0; - with_filenames = 0; - eolbyte = '\n'; - filename_mask = ~0; - - max_count = TYPE_MAXIMUM (off_t); - - /* The value -1 means to use DEFAULT_CONTEXT. */ - out_after = out_before = -1; - /* Default before/after context: chaged by -C/-NUM options */ - default_context = 0; - /* Changed by -o option */ - only_matching = 0; - - /* Internationalization. */ -#if defined(HAVE_SETLOCALE) - setlocale (LC_ALL, ""); -#endif -#if defined(ENABLE_NLS) - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif - - atexit (close_stdout); - - prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv); - - while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1) - switch (opt) - { - case 'A': - context_length_arg (optarg, &out_after); - break; - - case 'B': - context_length_arg (optarg, &out_before); - break; - - case 'C': - /* Set output match context, but let any explicit leading or - trailing amount specified with -A or -B stand. */ - context_length_arg (optarg, &default_context); - break; - - case 'D': - if (strcmp (optarg, "read") == 0) - devices = READ_DEVICES; - else if (strcmp (optarg, "skip") == 0) - devices = SKIP_DEVICES; - else - error (2, 0, _("unknown devices method")); - break; - - case 'E': - setmatcher ("egrep"); - break; - - case 'F': - setmatcher ("fgrep"); - break; - - case 'P': - setmatcher ("perl"); - break; - - case 'G': - setmatcher ("grep"); - break; - - case 'H': - with_filenames = 1; - break; - - case 'I': - binary_files = WITHOUT_MATCH_BINARY_FILES; - break; - case 'J': - if (Zflag) - { - printf (_("Cannot mix -Z and -J.\n")); - usage (2); - } - BZflag = 1; - break; - - case 'U': -#if defined(HAVE_DOS_FILE_CONTENTS) - dos_use_file_type = DOS_BINARY; -#endif - break; - - case 'u': -#if defined(HAVE_DOS_FILE_CONTENTS) - dos_report_unix_offset = 1; -#endif - break; - - case 'V': - show_version = 1; - break; - - case 'X': - setmatcher (optarg); - break; - - case 'a': - binary_files = TEXT_BINARY_FILES; - break; - - case 'b': - out_byte = 1; - break; - - case 'c': - count_matches = 1; - break; - - case 'd': - if (strcmp (optarg, "read") == 0) - directories = READ_DIRECTORIES; - else if (strcmp (optarg, "skip") == 0) - directories = SKIP_DIRECTORIES; - else if (strcmp (optarg, "recurse") == 0) - directories = RECURSE_DIRECTORIES; - else - error (2, 0, _("unknown directories method")); - break; - - case 'e': - cc = strlen (optarg); - keys = xrealloc (keys, keycc + cc + 1); - strcpy (&keys[keycc], optarg); - keycc += cc; - keys[keycc++] = '\n'; - break; - - case 'f': - fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin; - if (!fp) - error (2, errno, "%s", optarg); - for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2) - ; - keys = xrealloc (keys, keyalloc); - oldcc = keycc; - while (!feof (fp) - && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0) - { - keycc += cc; - if (keycc == keyalloc - 1) - keys = xrealloc (keys, keyalloc *= 2); - } - if (fp != stdin) - fclose(fp); - /* Append final newline if file ended in non-newline. */ - if (oldcc != keycc && keys[keycc - 1] != '\n') - keys[keycc++] = '\n'; - break; - - case 'h': - no_filenames = 1; - break; - - case 'i': - case 'y': /* For old-timers . . . */ - match_icase = 1; - break; - - case 'L': - /* Like -l, except list files that don't contain matches. - Inspired by the same option in Hume's gre. */ - list_files = -1; - break; - - case 'l': - list_files = 1; - break; - - case 'm': - { - uintmax_t value; - switch (xstrtoumax (optarg, 0, 10, &value, "")) - { - case LONGINT_OK: - max_count = value; - if (0 <= max_count && max_count == value) - break; - /* Fall through. */ - case LONGINT_OVERFLOW: - max_count = TYPE_MAXIMUM (off_t); - break; - - default: - error (2, 0, _("invalid max count")); - } - } - break; - - case 'n': - out_line = 1; - break; - - case 'o': - only_matching = 1; - break; - - case 'q': - exit_on_match = 1; - close_stdout_set_status(0); - break; - - case 'R': - case 'r': - directories = RECURSE_DIRECTORIES; - break; - - case 's': - suppress_errors = 1; - break; - - case 'v': - out_invert = 1; - break; - - case 'w': - match_words = 1; - break; - - case 'x': - match_lines = 1; - break; - - case 'Z': -#if HAVE_LIBZ > 0 - if (BZflag) - { - printf (_("Cannot mix -J and -Z.\n")); - usage (2); - } - Zflag = 1; -#else - filename_mask = 0; -#endif - break; - - case 'z': - eolbyte = '\0'; - break; - - case BINARY_FILES_OPTION: - if (strcmp (optarg, "binary") == 0) - binary_files = BINARY_BINARY_FILES; - else if (strcmp (optarg, "text") == 0) - binary_files = TEXT_BINARY_FILES; - else if (strcmp (optarg, "without-match") == 0) - binary_files = WITHOUT_MATCH_BINARY_FILES; - else - error (2, 0, _("unknown binary-files type")); - break; - - case COLOR_OPTION: - if(optarg) { - if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") || - !strcasecmp(optarg, "force")) - color_option = 1; - else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") || - !strcasecmp(optarg, "none")) - color_option = 0; - else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") || - !strcasecmp(optarg, "if-tty")) - color_option = 2; - else - show_help = 1; - } else - color_option = 2; - if(color_option == 2) { - if(isatty(STDOUT_FILENO) && getenv("TERM") && - strcmp(getenv("TERM"), "dumb")) - color_option = 1; - else - color_option = 0; - } - break; - - case EXCLUDE_OPTION: - if (!excluded_patterns) - excluded_patterns = new_exclude (); - add_exclude (excluded_patterns, optarg); - break; - - case EXCLUDE_FROM_OPTION: - if (!excluded_patterns) - excluded_patterns = new_exclude (); - if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n') - != 0) - { - error (2, errno, "%s", optarg); - } - break; - - case INCLUDE_OPTION: - if (!included_patterns) - included_patterns = new_exclude (); - add_exclude (included_patterns, optarg); - break; - - case LINE_BUFFERED_OPTION: - line_buffered = 1; - break; - - case LABEL_OPTION: - label = optarg; - break; - - case 0: - /* long options */ - break; - - default: - usage (2); - break; - - } - - /* POSIX.2 says that -q overrides -l, which in turn overrides the - other output options. */ - if (exit_on_match) - list_files = 0; - if (exit_on_match | list_files) - { - count_matches = 0; - done_on_match = 1; - } - out_quiet = count_matches | done_on_match; - - if (out_after < 0) - out_after = default_context; - if (out_before < 0) - out_before = default_context; - - if (color_option) - { - char *userval = getenv ("GREP_COLOR"); - if (userval != NULL && *userval != '\0') - grep_color = userval; - } - - if (! matcher) - matcher = program_name; - - if (show_version) - { - printf (_("%s (GNU grep) %s\n"), matcher, VERSION); - printf ("\n"); - printf (_("\ -Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n")); - printf (_("\ -This is free software; see the source for copying conditions. There is NO\n\ -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")); - printf ("\n"); - exit (0); - } - - if (show_help) - usage (0); - - if (keys) - { - if (keycc == 0) - { - /* No keys were specified (e.g. -f /dev/null). Match nothing. */ - out_invert ^= 1; - match_lines = match_words = 0; - } - else - /* Strip trailing newline. */ - --keycc; - } - else - if (optind < argc) - { - keys = argv[optind++]; - keycc = strlen (keys); - } - else - usage (2); - - if (!install_matcher (matcher) && !install_matcher ("default")) - abort (); - -#ifdef MBS_SUPPORT - if (MB_CUR_MAX != 1 && match_icase) - { - wchar_t wc; - mbstate_t cur_state, prev_state; - int i, len = strlen(keys); - - memset(&cur_state, 0, sizeof(mbstate_t)); - for (i = 0; i <= len ;) - { - size_t mbclen; - mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state); - if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0) - { - /* An invalid sequence, or a truncated multibyte character. - We treat it as a singlebyte character. */ - mbclen = 1; - } - else - { - if (iswupper((wint_t)wc)) - { - wc = towlower((wint_t)wc); - wcrtomb(keys + i, wc, &cur_state); - } - } - i += mbclen; - } - } -#endif /* MBS_SUPPORT */ - - (*compile)(keys, keycc); - - if ((argc - optind > 1 && !no_filenames) || with_filenames) - out_file = 1; - -#ifdef SET_BINARY - /* Output is set to binary mode because we shouldn't convert - NL to CR-LF pairs, especially when grepping binary files. */ - if (!isatty (1)) - SET_BINARY (1); -#endif - - if (max_count == 0) - exit (1); - - if (optind < argc) - { - status = 1; - do - { - char *file = argv[optind]; - if ((included_patterns || excluded_patterns) - && !isdir (file)) - { - if (included_patterns && - ! excluded_filename (included_patterns, file, 0)) - continue; - if (excluded_patterns && - excluded_filename (excluded_patterns, file, 0)) - continue; - } - status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file, - &stats_base); - } - while ( ++optind < argc); - } - else - status = grepfile ((char *) NULL, &stats_base); - - /* We register via atexit() to test stdout. */ - exit (errseen ? 2 : status); -} -/* vim:set shiftwidth=2: */ Index: gnu/usr.bin/grep/grepmat.c =================================================================== --- gnu/usr.bin/grep/grepmat.c +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif -#include "system.h" -#include "grep.h" -char const *matcher; Index: gnu/usr.bin/grep/hard-locale.h =================================================================== --- gnu/usr.bin/grep/hard-locale.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HARD_LOCALE_H_ -# define HARD_LOCALE_H_ 1 - -# if HAVE_CONFIG_H -# include -# endif - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -int hard_locale PARAMS ((int)); - -#endif /* HARD_LOCALE_H_ */ Index: gnu/usr.bin/grep/hard-locale.c =================================================================== --- gnu/usr.bin/grep/hard-locale.c +++ /dev/null @@ -1,87 +0,0 @@ -/* hard-locale.c -- Determine whether a locale is hard. - Copyright 1997, 1998, 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* $FreeBSD$ */ - -#if HAVE_CONFIG_H -# include -#endif - -#ifndef __GNUC__ -# ifdef HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - # pragma alloca -# else -# ifdef _WIN32 -# include -# include -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#if HAVE_LOCALE_H -# include -#endif - -#if HAVE_STRING_H -# include -#endif - -/* Return nonzero if the current CATEGORY locale is hard, i.e. if you - can't get away with assuming traditional C or POSIX behavior. */ -int -hard_locale (int category) -{ -#if ! HAVE_SETLOCALE - return 0; -#else - - int hard = 1; - char const *p = setlocale (category, 0); - - if (p) - { -# if defined(__FreeBSD__) || (defined __GLIBC__ && __GLIBC__ >= 2) - if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0) - hard = 0; -# else - char *locale = alloca (strlen (p) + 1); - strcpy (locale, p); - - /* Temporarily set the locale to the "C" and "POSIX" locales to - find their names, so that we can determine whether one or the - other is the caller's locale. */ - if (((p = setlocale (category, "C")) && strcmp (p, locale) == 0) - || ((p = setlocale (category, "POSIX")) && strcmp (p, locale) == 0)) - hard = 0; - - /* Restore the caller's locale. */ - setlocale (category, locale); -# endif - } - - return hard; - -#endif -} Index: gnu/usr.bin/grep/isdir.c =================================================================== --- gnu/usr.bin/grep/isdir.c +++ /dev/null @@ -1,42 +0,0 @@ -/* isdir.c -- determine whether a directory exists - Copyright (C) 1990, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include - -#if STAT_MACROS_BROKEN -# undef S_ISDIR -#endif - -#if !defined S_ISDIR && defined S_IFDIR -# define S_ISDIR(Mode) (((Mode) & S_IFMT) == S_IFDIR) -#endif - -/* If PATH is an existing directory or symbolic link to a directory, - return nonzero, else 0. */ - -int -isdir (const char *path) -{ - struct stat stats; - - return stat (path, &stats) == 0 && S_ISDIR (stats.st_mode); -} Index: gnu/usr.bin/grep/kwset.h =================================================================== --- gnu/usr.bin/grep/kwset.h +++ /dev/null @@ -1,59 +0,0 @@ -/* kwset.h - header declaring the keyword set library. - Copyright (C) 1989, 1998 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* Written August 1989 by Mike Haertel. - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -/* $FreeBSD$ */ - -struct kwsmatch -{ - int index; /* Index number of matching keyword. */ - size_t offset[1]; /* Offset of each submatch. */ - size_t size[1]; /* Length of each submatch. */ -}; - -typedef ptr_t kwset_t; - -/* Return an opaque pointer to a newly allocated keyword set, or NULL - if enough memory cannot be obtained. The argument if non-NULL - specifies a table of character translations to be applied to all - pattern and search text. */ -extern kwset_t kwsalloc PARAMS((char const *)); - -/* Incrementally extend the keyword set to include the given string. - Return NULL for success, or an error message. Remember an index - number for each keyword included in the set. */ -extern char *kwsincr PARAMS((kwset_t, char const *, size_t)); - -/* When the keyword set has been completely built, prepare it for - use. Return NULL for success, or an error message. */ -extern char *kwsprep PARAMS((kwset_t)); - -/* Search through the given buffer for a member of the keyword set. - Return a pointer to the leftmost longest match found, or NULL if - no match is found. If foundlen is non-NULL, store the length of - the matching substring in the integer it points to. Similarly, - if foundindex is non-NULL, store the index of the particular - keyword found therein. */ -extern size_t kwsexec PARAMS((kwset_t, char const *, size_t, struct kwsmatch *)); - -/* Deallocate the given keyword set and all its associated storage. */ -extern void kwsfree PARAMS((kwset_t)); - Index: gnu/usr.bin/grep/kwset.c =================================================================== --- gnu/usr.bin/grep/kwset.c +++ /dev/null @@ -1,773 +0,0 @@ -/* kwset.c - search for any of a set of keywords. - Copyright 1989, 1998, 2000 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* $FreeBSD$ */ - -/* Written August 1989 by Mike Haertel. - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation. */ - -/* The algorithm implemented by these routines bears a startling resemblence - to one discovered by Beate Commentz-Walter, although it is not identical. - See "A String Matching Algorithm Fast on the Average," Technical Report, - IBM-Germany, Scientific Center Heidelberg, Tiergartenstrasse 15, D-6900 - Heidelberg, Germany. See also Aho, A.V., and M. Corasick, "Efficient - String Matching: An Aid to Bibliographic Search," CACM June 1975, - Vol. 18, No. 6, which describes the failure function used below. */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include "system.h" -#include "kwset.h" -#include "obstack.h" - -#ifdef GREP -extern char *xmalloc(); -# undef malloc -# define malloc xmalloc -#endif - -#define NCHAR (UCHAR_MAX + 1) -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* Balanced tree of edges and labels leaving a given trie node. */ -struct tree -{ - struct tree *llink; /* Left link; MUST be first field. */ - struct tree *rlink; /* Right link (to larger labels). */ - struct trie *trie; /* Trie node pointed to by this edge. */ - unsigned char label; /* Label on this edge. */ - char balance; /* Difference in depths of subtrees. */ -}; - -/* Node of a trie representing a set of reversed keywords. */ -struct trie -{ - unsigned int accepting; /* Word index of accepted word, or zero. */ - struct tree *links; /* Tree of edges leaving this node. */ - struct trie *parent; /* Parent of this node. */ - struct trie *next; /* List of all trie nodes in level order. */ - struct trie *fail; /* Aho-Corasick failure function. */ - int depth; /* Depth of this node from the root. */ - int shift; /* Shift function for search failures. */ - int maxshift; /* Max shift of self and descendents. */ -}; - -/* Structure returned opaquely to the caller, containing everything. */ -struct kwset -{ - struct obstack obstack; /* Obstack for node allocation. */ - int words; /* Number of words in the trie. */ - struct trie *trie; /* The trie itself. */ - int mind; /* Minimum depth of an accepting node. */ - int maxd; /* Maximum depth of any node. */ - unsigned char delta[NCHAR]; /* Delta table for rapid search. */ - struct trie *next[NCHAR]; /* Table of children of the root. */ - char *target; /* Target string if there's only one. */ - int mind2; /* Used in Boyer-Moore search for one string. */ - char const *trans; /* Character translation table. */ -}; - -/* Allocate and initialize a keyword set object, returning an opaque - pointer to it. Return NULL if memory is not available. */ -kwset_t -kwsalloc (char const *trans) -{ - struct kwset *kwset; - - kwset = (struct kwset *) malloc(sizeof (struct kwset)); - if (!kwset) - return 0; - - obstack_init(&kwset->obstack); - kwset->words = 0; - kwset->trie - = (struct trie *) obstack_alloc(&kwset->obstack, sizeof (struct trie)); - if (!kwset->trie) - { - kwsfree((kwset_t) kwset); - return 0; - } - kwset->trie->accepting = 0; - kwset->trie->links = 0; - kwset->trie->parent = 0; - kwset->trie->next = 0; - kwset->trie->fail = 0; - kwset->trie->depth = 0; - kwset->trie->shift = 0; - kwset->mind = INT_MAX; - kwset->maxd = -1; - kwset->target = 0; - kwset->trans = trans; - - return (kwset_t) kwset; -} - -/* Add the given string to the contents of the keyword set. Return NULL - for success, an error message otherwise. */ -char * -kwsincr (kwset_t kws, char const *text, size_t len) -{ - struct kwset *kwset; - register struct trie *trie; - register unsigned char label; - register struct tree *link; - register int depth; - struct tree *links[12]; - enum { L, R } dirs[12]; - struct tree *t, *r, *l, *rl, *lr; - - kwset = (struct kwset *) kws; - trie = kwset->trie; - text += len; - - /* Descend the trie (built of reversed keywords) character-by-character, - installing new nodes when necessary. */ - while (len--) - { - label = kwset->trans ? kwset->trans[(unsigned char) *--text] : *--text; - - /* Descend the tree of outgoing links for this trie node, - looking for the current character and keeping track - of the path followed. */ - link = trie->links; - links[0] = (struct tree *) &trie->links; - dirs[0] = L; - depth = 1; - - while (link && label != link->label) - { - links[depth] = link; - if (label < link->label) - dirs[depth++] = L, link = link->llink; - else - dirs[depth++] = R, link = link->rlink; - } - - /* The current character doesn't have an outgoing link at - this trie node, so build a new trie node and install - a link in the current trie node's tree. */ - if (!link) - { - link = (struct tree *) obstack_alloc(&kwset->obstack, - sizeof (struct tree)); - if (!link) - return _("memory exhausted"); - link->llink = 0; - link->rlink = 0; - link->trie = (struct trie *) obstack_alloc(&kwset->obstack, - sizeof (struct trie)); - if (!link->trie) - return _("memory exhausted"); - link->trie->accepting = 0; - link->trie->links = 0; - link->trie->parent = trie; - link->trie->next = 0; - link->trie->fail = 0; - link->trie->depth = trie->depth + 1; - link->trie->shift = 0; - link->label = label; - link->balance = 0; - - /* Install the new tree node in its parent. */ - if (dirs[--depth] == L) - links[depth]->llink = link; - else - links[depth]->rlink = link; - - /* Back up the tree fixing the balance flags. */ - while (depth && !links[depth]->balance) - { - if (dirs[depth] == L) - --links[depth]->balance; - else - ++links[depth]->balance; - --depth; - } - - /* Rebalance the tree by pointer rotations if necessary. */ - if (depth && ((dirs[depth] == L && --links[depth]->balance) - || (dirs[depth] == R && ++links[depth]->balance))) - { - switch (links[depth]->balance) - { - case (char) -2: - switch (dirs[depth + 1]) - { - case L: - r = links[depth], t = r->llink, rl = t->rlink; - t->rlink = r, r->llink = rl; - t->balance = r->balance = 0; - break; - case R: - r = links[depth], l = r->llink, t = l->rlink; - rl = t->rlink, lr = t->llink; - t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl; - l->balance = t->balance != 1 ? 0 : -1; - r->balance = t->balance != (char) -1 ? 0 : 1; - t->balance = 0; - break; - default: - abort (); - } - break; - case 2: - switch (dirs[depth + 1]) - { - case R: - l = links[depth], t = l->rlink, lr = t->llink; - t->llink = l, l->rlink = lr; - t->balance = l->balance = 0; - break; - case L: - l = links[depth], r = l->rlink, t = r->llink; - lr = t->llink, rl = t->rlink; - t->llink = l, l->rlink = lr, t->rlink = r, r->llink = rl; - l->balance = t->balance != 1 ? 0 : -1; - r->balance = t->balance != (char) -1 ? 0 : 1; - t->balance = 0; - break; - default: - abort (); - } - break; - default: - abort (); - } - - if (dirs[depth - 1] == L) - links[depth - 1]->llink = t; - else - links[depth - 1]->rlink = t; - } - } - - trie = link->trie; - } - - /* Mark the node we finally reached as accepting, encoding the - index number of this word in the keyword set so far. */ - if (!trie->accepting) - trie->accepting = 1 + 2 * kwset->words; - ++kwset->words; - - /* Keep track of the longest and shortest string of the keyword set. */ - if (trie->depth < kwset->mind) - kwset->mind = trie->depth; - if (trie->depth > kwset->maxd) - kwset->maxd = trie->depth; - - return 0; -} - -/* Enqueue the trie nodes referenced from the given tree in the - given queue. */ -static void -enqueue (struct tree *tree, struct trie **last) -{ - if (!tree) - return; - enqueue(tree->llink, last); - enqueue(tree->rlink, last); - (*last) = (*last)->next = tree->trie; -} - -/* Compute the Aho-Corasick failure function for the trie nodes referenced - from the given tree, given the failure function for their parent as - well as a last resort failure node. */ -static void -treefails (register struct tree const *tree, struct trie const *fail, - struct trie *recourse) -{ - register struct tree *link; - - if (!tree) - return; - - treefails(tree->llink, fail, recourse); - treefails(tree->rlink, fail, recourse); - - /* Find, in the chain of fails going back to the root, the first - node that has a descendent on the current label. */ - while (fail) - { - link = fail->links; - while (link && tree->label != link->label) - if (tree->label < link->label) - link = link->llink; - else - link = link->rlink; - if (link) - { - tree->trie->fail = link->trie; - return; - } - fail = fail->fail; - } - - tree->trie->fail = recourse; -} - -/* Set delta entries for the links of the given tree such that - the preexisting delta value is larger than the current depth. */ -static void -treedelta (register struct tree const *tree, - register unsigned int depth, - unsigned char delta[]) -{ - if (!tree) - return; - treedelta(tree->llink, depth, delta); - treedelta(tree->rlink, depth, delta); - if (depth < delta[tree->label]) - delta[tree->label] = depth; -} - -/* Return true if A has every label in B. */ -static int -hasevery (register struct tree const *a, register struct tree const *b) -{ - if (!b) - return 1; - if (!hasevery(a, b->llink)) - return 0; - if (!hasevery(a, b->rlink)) - return 0; - while (a && b->label != a->label) - if (b->label < a->label) - a = a->llink; - else - a = a->rlink; - return !!a; -} - -/* Compute a vector, indexed by character code, of the trie nodes - referenced from the given tree. */ -static void -treenext (struct tree const *tree, struct trie *next[]) -{ - if (!tree) - return; - treenext(tree->llink, next); - treenext(tree->rlink, next); - next[tree->label] = tree->trie; -} - -/* Compute the shift for each trie node, as well as the delta - table and next cache for the given keyword set. */ -char * -kwsprep (kwset_t kws) -{ - register struct kwset *kwset; - register int i; - register struct trie *curr, *fail; - register char const *trans; - unsigned char delta[NCHAR]; - struct trie *last, *next[NCHAR]; - - kwset = (struct kwset *) kws; - - /* Initial values for the delta table; will be changed later. The - delta entry for a given character is the smallest depth of any - node at which an outgoing edge is labeled by that character. */ - if (kwset->mind < 256) - for (i = 0; i < NCHAR; ++i) - delta[i] = kwset->mind; - else - for (i = 0; i < NCHAR; ++i) - delta[i] = 255; - - /* Check if we can use the simple boyer-moore algorithm, instead - of the hairy commentz-walter algorithm. */ - if (kwset->words == 1 && kwset->trans == 0) - { - /* Looking for just one string. Extract it from the trie. */ - kwset->target = obstack_alloc(&kwset->obstack, kwset->mind); - for (i = kwset->mind - 1, curr = kwset->trie; i >= 0; --i) - { - kwset->target[i] = curr->links->label; - curr = curr->links->trie; - } - /* Build the Boyer Moore delta. Boy that's easy compared to CW. */ - for (i = 0; i < kwset->mind; ++i) - delta[(unsigned char) kwset->target[i]] = kwset->mind - (i + 1); - kwset->mind2 = kwset->mind; - /* Find the minimal delta2 shift that we might make after - a backwards match has failed. */ - for (i = 0; i < kwset->mind - 1; ++i) - if (kwset->target[i] == kwset->target[kwset->mind - 1]) - kwset->mind2 = kwset->mind - (i + 1); - } - else - { - /* Traverse the nodes of the trie in level order, simultaneously - computing the delta table, failure function, and shift function. */ - for (curr = last = kwset->trie; curr; curr = curr->next) - { - /* Enqueue the immediate descendents in the level order queue. */ - enqueue(curr->links, &last); - - curr->shift = kwset->mind; - curr->maxshift = kwset->mind; - - /* Update the delta table for the descendents of this node. */ - treedelta(curr->links, curr->depth, delta); - - /* Compute the failure function for the decendents of this node. */ - treefails(curr->links, curr->fail, kwset->trie); - - /* Update the shifts at each node in the current node's chain - of fails back to the root. */ - for (fail = curr->fail; fail; fail = fail->fail) - { - /* If the current node has some outgoing edge that the fail - doesn't, then the shift at the fail should be no larger - than the difference of their depths. */ - if (!hasevery(fail->links, curr->links)) - if (curr->depth - fail->depth < fail->shift) - fail->shift = curr->depth - fail->depth; - - /* If the current node is accepting then the shift at the - fail and its descendents should be no larger than the - difference of their depths. */ - if (curr->accepting && fail->maxshift > curr->depth - fail->depth) - fail->maxshift = curr->depth - fail->depth; - } - } - - /* Traverse the trie in level order again, fixing up all nodes whose - shift exceeds their inherited maxshift. */ - for (curr = kwset->trie->next; curr; curr = curr->next) - { - if (curr->maxshift > curr->parent->maxshift) - curr->maxshift = curr->parent->maxshift; - if (curr->shift > curr->maxshift) - curr->shift = curr->maxshift; - } - - /* Create a vector, indexed by character code, of the outgoing links - from the root node. */ - for (i = 0; i < NCHAR; ++i) - next[i] = 0; - treenext(kwset->trie->links, next); - - if ((trans = kwset->trans) != 0) - for (i = 0; i < NCHAR; ++i) - kwset->next[i] = next[(unsigned char) trans[i]]; - else - for (i = 0; i < NCHAR; ++i) - kwset->next[i] = next[i]; - } - - /* Fix things up for any translation table. */ - if ((trans = kwset->trans) != 0) - for (i = 0; i < NCHAR; ++i) - kwset->delta[i] = delta[(unsigned char) trans[i]]; - else - for (i = 0; i < NCHAR; ++i) - kwset->delta[i] = delta[i]; - - return 0; -} - -#define U(C) ((unsigned char) (C)) - -/* Fast boyer-moore search. */ -static size_t -bmexec (kwset_t kws, char const *text, size_t size) -{ - struct kwset const *kwset; - register unsigned char const *d1; - register char const *ep, *sp, *tp; - register int d, gc, i, len, md2; - - kwset = (struct kwset const *) kws; - len = kwset->mind; - - if (len == 0) - return 0; - if (len > size) - return -1; - if (len == 1) - { - tp = memchr (text, kwset->target[0], size); - return tp ? tp - text : -1; - } - - d1 = kwset->delta; - sp = kwset->target + len; - gc = U(sp[-2]); - md2 = kwset->mind2; - tp = text + len; - - /* Significance of 12: 1 (initial offset) + 10 (skip loop) + 1 (md2). */ - if (size > 12 * len) - /* 11 is not a bug, the initial offset happens only once. */ - for (ep = text + size - 11 * len;;) - { - while (tp <= ep) - { - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - if (d == 0) - goto found; - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - if (d == 0) - goto found; - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - if (d == 0) - goto found; - d = d1[U(tp[-1])], tp += d; - d = d1[U(tp[-1])], tp += d; - } - break; - found: - if (U(tp[-2]) == gc) - { - for (i = 3; i <= len && U(tp[-i]) == U(sp[-i]); ++i) - ; - if (i > len) - return tp - len - text; - } - tp += md2; - } - - /* Now we have only a few characters left to search. We - carefully avoid ever producing an out-of-bounds pointer. */ - ep = text + size; - d = d1[U(tp[-1])]; - while (d <= ep - tp) - { - d = d1[U((tp += d)[-1])]; - if (d != 0) - continue; - if (U(tp[-2]) == gc) - { - for (i = 3; i <= len && U(tp[-i]) == U(sp[-i]); ++i) - ; - if (i > len) - return tp - len - text; - } - d = md2; - } - - return -1; -} - -/* Hairy multiple string search. */ -static size_t -cwexec (kwset_t kws, char const *text, size_t len, struct kwsmatch *kwsmatch) -{ - struct kwset const *kwset; - struct trie * const *next; - struct trie const *trie; - struct trie const *accept; - char const *beg, *lim, *mch, *lmch; - register unsigned char c; - register unsigned char const *delta; - register int d; - register char const *end, *qlim; - register struct tree const *tree; - register char const *trans; - -#ifdef lint - accept = NULL; -#endif - - /* Initialize register copies and look for easy ways out. */ - kwset = (struct kwset *) kws; - if (len < kwset->mind) - return -1; - next = kwset->next; - delta = kwset->delta; - trans = kwset->trans; - lim = text + len; - end = text; - if ((d = kwset->mind) != 0) - mch = 0; - else - { - mch = text, accept = kwset->trie; - goto match; - } - - if (len >= 4 * kwset->mind) - qlim = lim - 4 * kwset->mind; - else - qlim = 0; - - while (lim - end >= d) - { - if (qlim && end <= qlim) - { - end += d - 1; - while ((d = delta[c = *end]) && end < qlim) - { - end += d; - end += delta[(unsigned char) *end]; - end += delta[(unsigned char) *end]; - } - ++end; - } - else - d = delta[c = (end += d)[-1]]; - if (d) - continue; - beg = end - 1; - trie = next[c]; - if (trie->accepting) - { - mch = beg; - accept = trie; - } - d = trie->shift; - while (beg > text) - { - c = trans ? trans[(unsigned char) *--beg] : *--beg; - tree = trie->links; - while (tree && c != tree->label) - if (c < tree->label) - tree = tree->llink; - else - tree = tree->rlink; - if (tree) - { - trie = tree->trie; - if (trie->accepting) - { - mch = beg; - accept = trie; - } - } - else - break; - d = trie->shift; - } - if (mch) - goto match; - } - return -1; - - match: - /* Given a known match, find the longest possible match anchored - at or before its starting point. This is nearly a verbatim - copy of the preceding main search loops. */ - if (lim - mch > kwset->maxd) - lim = mch + kwset->maxd; - lmch = 0; - d = 1; - while (lim - end >= d) - { - if ((d = delta[c = (end += d)[-1]]) != 0) - continue; - beg = end - 1; - if (!(trie = next[c])) - { - d = 1; - continue; - } - if (trie->accepting && beg <= mch) - { - lmch = beg; - accept = trie; - } - d = trie->shift; - while (beg > text) - { - c = trans ? trans[(unsigned char) *--beg] : *--beg; - tree = trie->links; - while (tree && c != tree->label) - if (c < tree->label) - tree = tree->llink; - else - tree = tree->rlink; - if (tree) - { - trie = tree->trie; - if (trie->accepting && beg <= mch) - { - lmch = beg; - accept = trie; - } - } - else - break; - d = trie->shift; - } - if (lmch) - { - mch = lmch; - goto match; - } - if (!d) - d = 1; - } - - if (kwsmatch) - { - kwsmatch->index = accept->accepting / 2; - kwsmatch->offset[0] = mch - text; - kwsmatch->size[0] = accept->depth; - } - return mch - text; -} - -/* Search through the given text for a match of any member of the - given keyword set. Return a pointer to the first character of - the matching substring, or NULL if no match is found. If FOUNDLEN - is non-NULL store in the referenced location the length of the - matching substring. Similarly, if FOUNDIDX is non-NULL, store - in the referenced location the index number of the particular - keyword matched. */ -size_t -kwsexec (kwset_t kws, char const *text, size_t size, - struct kwsmatch *kwsmatch) -{ - struct kwset const *kwset = (struct kwset *) kws; - if (kwset->words == 1 && kwset->trans == 0) - { - size_t ret = bmexec (kws, text, size); - if (kwsmatch != 0 && ret != (size_t) -1) - { - kwsmatch->index = 0; - kwsmatch->offset[0] = ret; - kwsmatch->size[0] = kwset->mind; - } - return ret; - } - else - return cwexec(kws, text, size, kwsmatch); -} - -/* Free the components of the given keyword set. */ -void -kwsfree (kwset_t kws) -{ - struct kwset *kwset; - - kwset = (struct kwset *) kws; - obstack_free(&kwset->obstack, 0); - free(kws); -} Index: gnu/usr.bin/grep/obstack.h =================================================================== --- gnu/usr.bin/grep/obstack.h +++ /dev/null @@ -1,593 +0,0 @@ -/* obstack.h - object stack macros - Copyright (C) 1988,89,90,91,92,93,94,96,97,98,99 Free Software Foundation, Inc. - - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Summary: - -All the apparent functions defined here are macros. The idea -is that you would use these pre-tested macros to solve a -very specific set of problems, and they would run fast. -Caution: no side-effects in arguments please!! They may be -evaluated MANY times!! - -These macros operate a stack of objects. Each object starts life -small, and may grow to maturity. (Consider building a word syllable -by syllable.) An object can move while it is growing. Once it has -been "finished" it never changes address again. So the "top of the -stack" is typically an immature growing object, while the rest of the -stack is of mature, fixed size and fixed address objects. - -These routines grab large chunks of memory, using a function you -supply, called `obstack_chunk_alloc'. On occasion, they free chunks, -by calling `obstack_chunk_free'. You must define them and declare -them before using any obstack macros. - -Each independent stack is represented by a `struct obstack'. -Each of the obstack macros expects a pointer to such a structure -as the first argument. - -One motivation for this package is the problem of growing char strings -in symbol tables. Unless you are "fascist pig with a read-only mind" ---Gosper's immortal quote from HAKMEM item 154, out of context--you -would not like to put any arbitrary upper limit on the length of your -symbols. - -In practice this often means you will build many short symbols and a -few long symbols. At the time you are reading a symbol you don't know -how long it is. One traditional method is to read a symbol into a -buffer, realloc()ating the buffer every time you try to read a symbol -that is longer than the buffer. This is beaut, but you still will -want to copy the symbol from the buffer to a more permanent -symbol-table entry say about half the time. - -With obstacks, you can work differently. Use one obstack for all symbol -names. As you read a symbol, grow the name in the obstack gradually. -When the name is complete, finalize it. Then, if the symbol exists already, -free the newly read name. - -The way we do this is to take a large chunk, allocating memory from -low addresses. When you want to build a symbol in the chunk you just -add chars above the current "high water mark" in the chunk. When you -have finished adding chars, because you got to the end of the symbol, -you know how long the chars are, and you can create a new object. -Mostly the chars will not burst over the highest address of the chunk, -because you would typically expect a chunk to be (say) 100 times as -long as an average object. - -In case that isn't clear, when we have enough chars to make up -the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) -so we just point to it where it lies. No moving of chars is -needed and this is the second win: potentially long strings need -never be explicitly shuffled. Once an object is formed, it does not -change its address during its lifetime. - -When the chars burst over a chunk boundary, we allocate a larger -chunk, and then copy the partly formed object from the end of the old -chunk to the beginning of the new larger chunk. We then carry on -accreting characters to the end of the object as we normally would. - -A special macro is provided to add a single char at a time to a -growing object. This allows the use of register variables, which -break the ordinary 'growth' macro. - -Summary: - We allocate large chunks. - We carve out one object at a time from the current chunk. - Once carved, an object never moves. - We are free to append data of any size to the currently - growing object. - Exactly one object is growing in an obstack at any one time. - You can run one obstack per control block. - You may have as many control blocks as you dare. - Because of the way we do it, you can `unwind' an obstack - back to a previous state. (You may remove objects much - as you would with a stack.) -*/ - - -/* Don't do the contents of this file more than once. */ - -#ifndef _OBSTACK_H -#define _OBSTACK_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* We use subtraction of (char *) 0 instead of casting to int - because on word-addressable machines a simple cast to int - may ignore the byte-within-word field of the pointer. */ - -#ifndef __PTR_TO_INT -# define __PTR_TO_INT(P) ((P) - (char *) 0) -#endif - -#ifndef __INT_TO_PTR -# define __INT_TO_PTR(P) ((P) + (char *) 0) -#endif - -/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is - defined, as with GNU C, use that; that way we don't pollute the - namespace with 's symbols. Otherwise, if is - available, include it and use ptrdiff_t. In traditional C, long is - the best that we can do. */ - -#ifdef __PTRDIFF_TYPE__ -# define PTR_INT_TYPE __PTRDIFF_TYPE__ -#else -# ifdef HAVE_STDDEF_H -# include -# define PTR_INT_TYPE ptrdiff_t -# else -# define PTR_INT_TYPE long -# endif -#endif - -#if defined _LIBC || defined HAVE_STRING_H -# include -# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) -#else -# ifdef memcpy -# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) -# else -# define _obstack_memcpy(To, From, N) bcopy ((From), (To), (N)) -# endif -#endif - -struct _obstack_chunk /* Lives at front of each chunk. */ -{ - char *limit; /* 1 past end of this chunk */ - struct _obstack_chunk *prev; /* address of prior chunk or NULL */ - char contents[4]; /* objects begin here */ -}; - -struct obstack /* control current object in current chunk */ -{ - long chunk_size; /* preferred size to allocate chunks in */ - struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ - char *object_base; /* address of object we are building */ - char *next_free; /* where to add next char to current object */ - char *chunk_limit; /* address of char after current chunk */ - PTR_INT_TYPE temp; /* Temporary for some macros. */ - int alignment_mask; /* Mask of alignment for each object. */ -#if defined __STDC__ && __STDC__ - /* These prototypes vary based on `use_extra_arg', and we use - casts to the prototypeless function type in all assignments, - but having prototypes here quiets -Wstrict-prototypes. */ - struct _obstack_chunk *(*chunkfun) (void *, long); - void (*freefun) (void *, struct _obstack_chunk *); - void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ -#else - struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ - void (*freefun) (); /* User's function to free a chunk. */ - char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ -#endif - unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ - unsigned maybe_empty_object:1;/* There is a possibility that the current - chunk contains a zero-length object. This - prevents freeing the chunk if we allocate - a bigger chunk to replace it. */ - unsigned alloc_failed:1; /* No longer used, as we now call the failed - handler on error, but retained for binary - compatibility. */ -}; - -/* Declare the external functions we use; they are in obstack.c. */ - -#if defined __STDC__ && __STDC__ -extern void _obstack_newchunk (struct obstack *, int); -extern void _obstack_free (struct obstack *, void *); -extern int _obstack_begin (struct obstack *, int, int, - void *(*) (long), void (*) (void *)); -extern int _obstack_begin_1 (struct obstack *, int, int, - void *(*) (void *, long), - void (*) (void *, void *), void *); -extern int _obstack_memory_used (struct obstack *); -#else -extern void _obstack_newchunk (); -extern void _obstack_free (); -extern int _obstack_begin (); -extern int _obstack_begin_1 (); -extern int _obstack_memory_used (); -#endif - -#if defined __STDC__ && __STDC__ - -/* Do the function-declarations after the structs - but before defining the macros. */ - -void obstack_init (struct obstack *obstack); - -void * obstack_alloc (struct obstack *obstack, int size); - -void * obstack_copy (struct obstack *obstack, void *address, int size); -void * obstack_copy0 (struct obstack *obstack, void *address, int size); - -void obstack_free (struct obstack *obstack, void *block); - -void obstack_blank (struct obstack *obstack, int size); - -void obstack_grow (struct obstack *obstack, void *data, int size); -void obstack_grow0 (struct obstack *obstack, void *data, int size); - -void obstack_1grow (struct obstack *obstack, int data_char); -void obstack_ptr_grow (struct obstack *obstack, void *data); -void obstack_int_grow (struct obstack *obstack, int data); - -void * obstack_finish (struct obstack *obstack); - -int obstack_object_size (struct obstack *obstack); - -int obstack_room (struct obstack *obstack); -void obstack_make_room (struct obstack *obstack, int size); -void obstack_1grow_fast (struct obstack *obstack, int data_char); -void obstack_ptr_grow_fast (struct obstack *obstack, void *data); -void obstack_int_grow_fast (struct obstack *obstack, int data); -void obstack_blank_fast (struct obstack *obstack, int size); - -void * obstack_base (struct obstack *obstack); -void * obstack_next_free (struct obstack *obstack); -int obstack_alignment_mask (struct obstack *obstack); -int obstack_chunk_size (struct obstack *obstack); -int obstack_memory_used (struct obstack *obstack); - -#endif /* __STDC__ */ - -/* Non-ANSI C cannot really support alternative functions for these macros, - so we do not declare them. */ - -/* Error handler called when `obstack_chunk_alloc' failed to allocate - more memory. This can be set to a user defined function which - should either abort gracefully or use longjump - but shouldn't - return. The default action is to print a message and abort. */ -#if defined __STDC__ && __STDC__ -extern void (*obstack_alloc_failed_handler) (void); -#else -extern void (*obstack_alloc_failed_handler) (); -#endif - -/* Exit value used when `print_and_abort' is used. */ -extern int obstack_exit_failure; - -/* Pointer to beginning of object being allocated or to be allocated next. - Note that this might not be the final address of the object - because a new chunk might be needed to hold the final size. */ - -#define obstack_base(h) ((h)->object_base) - -/* Size for allocating ordinary chunks. */ - -#define obstack_chunk_size(h) ((h)->chunk_size) - -/* Pointer to next byte not yet allocated in current chunk. */ - -#define obstack_next_free(h) ((h)->next_free) - -/* Mask specifying low bits that should be clear in address of an object. */ - -#define obstack_alignment_mask(h) ((h)->alignment_mask) - -/* To prevent prototype warnings provide complete argument list in - standard C version. */ -#if defined __STDC__ && __STDC__ - -# define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) - -# define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) - -# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) - -# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) (void *, long)) (chunkfun), \ - (void (*) (void *, void *)) (freefun), (arg)) - -# define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) - -# define obstack_freefun(h, newfreefun) \ - ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) - -#else - -# define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -# define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) - -# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) - -# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) - -# define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) - -# define obstack_freefun(h, newfreefun) \ - ((h) -> freefun = (void (*)()) (newfreefun)) - -#endif - -#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) - -#define obstack_blank_fast(h,n) ((h)->next_free += (n)) - -#define obstack_memory_used(h) _obstack_memory_used (h) - -#if defined __GNUC__ && defined __STDC__ && __STDC__ -/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and - does not implement __extension__. But that compiler doesn't define - __GNUC_MINOR__. */ -# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) -# define __extension__ -# endif - -/* For GNU C, if not -traditional, - we can define these macros to compute all args only once - without using a global variable. - Also, we can avoid using the `temp' slot, to make faster code. */ - -# define obstack_object_size(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - (unsigned) (__o->next_free - __o->object_base); }) - -# define obstack_room(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - (unsigned) (__o->chunk_limit - __o->next_free); }) - -# define obstack_make_room(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - (void) 0; }) - -# define obstack_empty_p(OBSTACK) \ - __extension__ \ - ({ struct obstack *__o = (OBSTACK); \ - (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) - -# define obstack_grow(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len > __o->chunk_limit) \ - _obstack_newchunk (__o, __len); \ - _obstack_memcpy (__o->next_free, (char *) (where), __len); \ - __o->next_free += __len; \ - (void) 0; }) - -# define obstack_grow0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, __len + 1); \ - _obstack_memcpy (__o->next_free, (char *) (where), __len); \ - __o->next_free += __len; \ - *(__o->next_free)++ = 0; \ - (void) 0; }) - -# define obstack_1grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, 1); \ - *(__o->next_free)++ = (datum); \ - (void) 0; }) - -/* These assume that the obstack alignment is good enough for pointers or ints, - and that the data added so far to the current object - shares that much alignment. */ - -# define obstack_ptr_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (void *)); \ - *((void **)__o->next_free)++ = ((void *)datum); \ - (void) 0; }) - -# define obstack_int_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (int) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (int)); \ - *((int *)__o->next_free)++ = ((int)datum); \ - (void) 0; }) - -# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr) -# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint) - -# define obstack_blank(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - __o->next_free += __len; \ - (void) 0; }) - -# define obstack_alloc(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_blank (__h, (length)); \ - obstack_finish (__h); }) - -# define obstack_copy(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow (__h, (where), (length)); \ - obstack_finish (__h); }) - -# define obstack_copy0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow0 (__h, (where), (length)); \ - obstack_finish (__h); }) - -/* The local variable is named __o1 to avoid a name conflict - when obstack_blank is called. */ -# define obstack_finish(OBSTACK) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - void *value; \ - value = (void *) __o1->object_base; \ - if (__o1->next_free == value) \ - __o1->maybe_empty_object = 1; \ - __o1->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ - & ~ (__o1->alignment_mask)); \ - if (__o1->next_free - (char *)__o1->chunk \ - > __o1->chunk_limit - (char *)__o1->chunk) \ - __o1->next_free = __o1->chunk_limit; \ - __o1->object_base = __o1->next_free; \ - value; }) - -# define obstack_free(OBSTACK, OBJ) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ - if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ - __o->next_free = __o->object_base = (char *)__obj; \ - else (obstack_free) (__o, __obj); }) - -#else /* not __GNUC__ or not __STDC__ */ - -# define obstack_object_size(h) \ - (unsigned) ((h)->next_free - (h)->object_base) - -# define obstack_room(h) \ - (unsigned) ((h)->chunk_limit - (h)->next_free) - -# define obstack_empty_p(h) \ - ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) - -/* Note that the call to _obstack_newchunk is enclosed in (..., 0) - so that we can avoid having void expressions - in the arms of the conditional expression. - Casting the third operand to void was tried before, - but some compilers won't accept it. */ - -# define obstack_make_room(h,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) - -# define obstack_grow(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \ - (h)->next_free += (h)->temp) - -# define obstack_grow0(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ - _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \ - (h)->next_free += (h)->temp, \ - *((h)->next_free)++ = 0) - -# define obstack_1grow(h,datum) \ -( (((h)->next_free + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), 1), 0) : 0), \ - (*((h)->next_free)++ = (datum))) - -# define obstack_ptr_grow(h,datum) \ -( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ - (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum))) - -# define obstack_int_grow(h,datum) \ -( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ - (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum))) - -# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr) -# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint) - -# define obstack_blank(h,length) \ -( (h)->temp = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - ((h)->next_free += (h)->temp)) - -# define obstack_alloc(h,length) \ - (obstack_blank ((h), (length)), obstack_finish ((h))) - -# define obstack_copy(h,where,length) \ - (obstack_grow ((h), (where), (length)), obstack_finish ((h))) - -# define obstack_copy0(h,where,length) \ - (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) - -# define obstack_finish(h) \ -( ((h)->next_free == (h)->object_base \ - ? (((h)->maybe_empty_object = 1), 0) \ - : 0), \ - (h)->temp = __PTR_TO_INT ((h)->object_base), \ - (h)->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ - & ~ ((h)->alignment_mask)), \ - (((h)->next_free - (char *) (h)->chunk \ - > (h)->chunk_limit - (char *) (h)->chunk) \ - ? ((h)->next_free = (h)->chunk_limit) : 0), \ - (h)->object_base = (h)->next_free, \ - __INT_TO_PTR ((h)->temp)) - -# if defined __STDC__ && __STDC__ -# define obstack_free(h,obj) \ -( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) -# else -# define obstack_free(h,obj) \ -( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) -# endif - -#endif /* not __GNUC__ or not __STDC__ */ - -#ifdef __cplusplus -} /* C++ */ -#endif - -#endif /* obstack.h */ Index: gnu/usr.bin/grep/obstack.c =================================================================== --- gnu/usr.bin/grep/obstack.c +++ /dev/null @@ -1,598 +0,0 @@ -/* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988-1994,96,97,98,99 Free Software Foundation, Inc. - - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "obstack.h" - -/* NOTE BEFORE MODIFYING THIS FILE: This version number must be - incremented whenever callers compiled using an old obstack.h can no - longer properly call the functions in this obstack.c. */ -#define OBSTACK_INTERFACE_VERSION 1 - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself, and the installed library - supports the same library interface we do. This code is part of the GNU - C Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object - files, it is simpler to just do this in the source for each such file. */ - -#include /* Random thing to get __GNU_LIBRARY__. */ -#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 -#include -#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - - -#ifndef ELIDE_CODE - - -#if defined (__STDC__) && __STDC__ -#define POINTER void * -#else -#define POINTER char * -#endif - -/* Determine default alignment. */ -struct fooalign {char x; double d;}; -#define DEFAULT_ALIGNMENT \ - ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0)) -/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. - But in fact it might be less smart and round addresses to as much as - DEFAULT_ROUNDING. So we prepare for it to do that. */ -union fooround {long x; double d;}; -#define DEFAULT_ROUNDING (sizeof (union fooround)) - -/* When we copy a long block of data, this is the unit to do it with. - On some machines, copying successive ints does not work; - in such a case, redefine COPYING_UNIT to `long' (if that works) - or `char' as a last resort. */ -#ifndef COPYING_UNIT -#define COPYING_UNIT int -#endif - - -/* The functions allocating more room by calling `obstack_chunk_alloc' - jump to the handler pointed to by `obstack_alloc_failed_handler'. - This can be set to a user defined function which should either - abort gracefully or use longjump - but shouldn't return. This - variable by default points to the internal function - `print_and_abort'. */ -#if defined (__STDC__) && __STDC__ -static void print_and_abort (void); -void (*obstack_alloc_failed_handler) (void) = print_and_abort; -#else -static void print_and_abort (); -void (*obstack_alloc_failed_handler) () = print_and_abort; -#endif - -/* Exit value used when `print_and_abort' is used. */ -#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H -#include -#endif -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif -int obstack_exit_failure = EXIT_FAILURE; - -/* The non-GNU-C macros copy the obstack into this global variable - to avoid multiple evaluation. */ - -struct obstack *_obstack; - -/* Define a macro that either calls functions with the traditional malloc/free - calling interface, or calls functions with the mmalloc/mfree interface - (that adds an extra first argument), based on the state of use_extra_arg. - For free, do not use ?:, since some compilers, like the MIPS compilers, - do not allow (expr) ? void : void. */ - -#if defined (__STDC__) && __STDC__ -#define CALL_CHUNKFUN(h, size) \ - (((h) -> use_extra_arg) \ - ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ - : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) - -#define CALL_FREEFUN(h, old_chunk) \ - do { \ - if ((h) -> use_extra_arg) \ - (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ - else \ - (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ - } while (0) -#else -#define CALL_CHUNKFUN(h, size) \ - (((h) -> use_extra_arg) \ - ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ - : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size))) - -#define CALL_FREEFUN(h, old_chunk) \ - do { \ - if ((h) -> use_extra_arg) \ - (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ - else \ - (*(void (*) ()) (h)->freefun) ((old_chunk)); \ - } while (0) -#endif - - -/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). - Objects start on multiples of ALIGNMENT (0 means use default). - CHUNKFUN is the function to use to allocate chunks, - and FREEFUN the function to free them. - - Return nonzero if successful, calls obstack_alloc_failed_handler if - allocation fails. */ - -int -_obstack_begin (h, size, alignment, chunkfun, freefun) - struct obstack *h; - int size; - int alignment; -#if defined (__STDC__) && __STDC__ - POINTER (*chunkfun) (long); - void (*freefun) (void *); -#else - POINTER (*chunkfun) (); - void (*freefun) (); -#endif -{ - register struct _obstack_chunk *chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = (int) DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - -#if defined (__STDC__) && __STDC__ - h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; - h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; -#else - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; -#endif - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->use_extra_arg = 0; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = chunk->contents; - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - h->alloc_failed = 0; - return 1; -} - -int -_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) - struct obstack *h; - int size; - int alignment; -#if defined (__STDC__) && __STDC__ - POINTER (*chunkfun) (POINTER, long); - void (*freefun) (POINTER, POINTER); -#else - POINTER (*chunkfun) (); - void (*freefun) (); -#endif - POINTER arg; -{ - register struct _obstack_chunk *chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = (int) DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - -#if defined(__STDC__) && __STDC__ - h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; - h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; -#else - h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; - h->freefun = freefun; -#endif - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->extra_arg = arg; - h->use_extra_arg = 1; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = chunk->contents; - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - h->alloc_failed = 0; - return 1; -} - -/* Allocate a new current chunk for the obstack *H - on the assumption that LENGTH bytes need to be added - to the current object, or a new object of length LENGTH allocated. - Copies any partial object from the end of the old chunk - to the beginning of the new one. */ - -void -_obstack_newchunk (h, length) - struct obstack *h; - int length; -{ - register struct _obstack_chunk *old_chunk = h->chunk; - register struct _obstack_chunk *new_chunk; - register long new_size; - register long obj_size = h->next_free - h->object_base; - register long i; - long already; - - /* Compute size for new chunk. */ - new_size = (obj_size + length) + (obj_size >> 3) + 100; - if (new_size < h->chunk_size) - new_size = h->chunk_size; - - /* Allocate and initialize the new chunk. */ - new_chunk = CALL_CHUNKFUN (h, new_size); - if (!new_chunk) - (*obstack_alloc_failed_handler) (); - h->chunk = new_chunk; - new_chunk->prev = old_chunk; - new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; - - /* Move the existing object to the new chunk. - Word at a time is fast and is safe if the object - is sufficiently aligned. */ - if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) - { - for (i = obj_size / sizeof (COPYING_UNIT) - 1; - i >= 0; i--) - ((COPYING_UNIT *)new_chunk->contents)[i] - = ((COPYING_UNIT *)h->object_base)[i]; - /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, - but that can cross a page boundary on a machine - which does not do strict alignment for COPYING_UNITS. */ - already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); - } - else - already = 0; - /* Copy remaining bytes one by one. */ - for (i = already; i < obj_size; i++) - new_chunk->contents[i] = h->object_base[i]; - - /* If the object just copied was the only data in OLD_CHUNK, - free that chunk and remove it from the chain. - But not if that chunk might contain an empty object. */ - if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) - { - new_chunk->prev = old_chunk->prev; - CALL_FREEFUN (h, old_chunk); - } - - h->object_base = new_chunk->contents; - h->next_free = h->object_base + obj_size; - /* The new chunk certainly contains no empty object yet. */ - h->maybe_empty_object = 0; -} - -/* Return nonzero if object OBJ has been allocated from obstack H. - This is here for debugging. - If you use it in a program, you are probably losing. */ - -#if defined (__STDC__) && __STDC__ -/* Suppress -Wmissing-prototypes warning. We don't want to declare this in - obstack.h because it is just for debugging. */ -int _obstack_allocated_p (struct obstack *h, POINTER obj); -#endif - -int -_obstack_allocated_p (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk *plp; /* point to previous chunk if any */ - - lp = (h)->chunk; - /* We use >= rather than > since the object cannot be exactly at - the beginning of the chunk but might be an empty object exactly - at the end of an adjacent chunk. */ - while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj)) - { - plp = lp->prev; - lp = plp; - } - return lp != 0; -} - -/* Free objects in obstack H, including OBJ and everything allocate - more recently than OBJ. If OBJ is zero, free everything in H. */ - -#undef obstack_free - -/* This function has two names with identical definitions. - This is the first one, called from non-ANSI code. */ - -void -_obstack_free (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk *plp; /* point to previous chunk if any */ - - lp = h->chunk; - /* We use >= because there cannot be an object at the beginning of a chunk. - But there can be an empty object at that address - at the end of another chunk. */ - while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj)) - { - plp = lp->prev; - CALL_FREEFUN (h, lp); - lp = plp; - /* If we switch chunks, we can't tell whether the new current - chunk contains an empty object, so assume that it may. */ - h->maybe_empty_object = 1; - } - if (lp) - { - h->object_base = h->next_free = (char *) (obj); - h->chunk_limit = lp->limit; - h->chunk = lp; - } - else if (obj != 0) - /* obj is not in any of the chunks! */ - abort (); -} - -/* This function is used from ANSI code. */ - -void -obstack_free (h, obj) - struct obstack *h; - POINTER obj; -{ - register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk *plp; /* point to previous chunk if any */ - - lp = h->chunk; - /* We use >= because there cannot be an object at the beginning of a chunk. - But there can be an empty object at that address - at the end of another chunk. */ - while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj)) - { - plp = lp->prev; - CALL_FREEFUN (h, lp); - lp = plp; - /* If we switch chunks, we can't tell whether the new current - chunk contains an empty object, so assume that it may. */ - h->maybe_empty_object = 1; - } - if (lp) - { - h->object_base = h->next_free = (char *) (obj); - h->chunk_limit = lp->limit; - h->chunk = lp; - } - else if (obj != 0) - /* obj is not in any of the chunks! */ - abort (); -} - -int -_obstack_memory_used (h) - struct obstack *h; -{ - register struct _obstack_chunk* lp; - register int nbytes = 0; - - for (lp = h->chunk; lp != 0; lp = lp->prev) - { - nbytes += lp->limit - (char *) lp; - } - return nbytes; -} - -/* Define the error handler. */ -#ifndef _ -# ifdef HAVE_LIBINTL_H -# include -# ifndef _ -# define _(Str) gettext (Str) -# endif -# else -# define _(Str) (Str) -# endif -#endif -#if defined _LIBC && defined USE_IN_LIBIO -# include -# define fputs(s, f) _IO_fputs (s, f) -#endif - -static void -print_and_abort () -{ - fputs (_("memory exhausted"), stderr); - fputc ('\n', stderr); - exit (obstack_exit_failure); -} - -#if 0 -/* These are now turned off because the applications do not use it - and it uses bcopy via obstack_grow, which causes trouble on sysV. */ - -/* Now define the functional versions of the obstack macros. - Define them to simply use the corresponding macros to do the job. */ - -#if defined (__STDC__) && __STDC__ -/* These function definitions do not work with non-ANSI preprocessors; - they won't pass through the macro names in parentheses. */ - -/* The function names appear in parentheses in order to prevent - the macro-definitions of the names from being expanded there. */ - -POINTER (obstack_base) (obstack) - struct obstack *obstack; -{ - return obstack_base (obstack); -} - -POINTER (obstack_next_free) (obstack) - struct obstack *obstack; -{ - return obstack_next_free (obstack); -} - -int (obstack_object_size) (obstack) - struct obstack *obstack; -{ - return obstack_object_size (obstack); -} - -int (obstack_room) (obstack) - struct obstack *obstack; -{ - return obstack_room (obstack); -} - -int (obstack_make_room) (obstack, length) - struct obstack *obstack; - int length; -{ - return obstack_make_room (obstack, length); -} - -void (obstack_grow) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - obstack_grow (obstack, pointer, length); -} - -void (obstack_grow0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - obstack_grow0 (obstack, pointer, length); -} - -void (obstack_1grow) (obstack, character) - struct obstack *obstack; - int character; -{ - obstack_1grow (obstack, character); -} - -void (obstack_blank) (obstack, length) - struct obstack *obstack; - int length; -{ - obstack_blank (obstack, length); -} - -void (obstack_1grow_fast) (obstack, character) - struct obstack *obstack; - int character; -{ - obstack_1grow_fast (obstack, character); -} - -void (obstack_blank_fast) (obstack, length) - struct obstack *obstack; - int length; -{ - obstack_blank_fast (obstack, length); -} - -POINTER (obstack_finish) (obstack) - struct obstack *obstack; -{ - return obstack_finish (obstack); -} - -POINTER (obstack_alloc) (obstack, length) - struct obstack *obstack; - int length; -{ - return obstack_alloc (obstack, length); -} - -POINTER (obstack_copy) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - return obstack_copy (obstack, pointer, length); -} - -POINTER (obstack_copy0) (obstack, pointer, length) - struct obstack *obstack; - POINTER pointer; - int length; -{ - return obstack_copy0 (obstack, pointer, length); -} - -#endif /* __STDC__ */ - -#endif /* 0 */ - -#endif /* !ELIDE_CODE */ Index: gnu/usr.bin/grep/quotearg.h =================================================================== --- gnu/usr.bin/grep/quotearg.h +++ /dev/null @@ -1,110 +0,0 @@ -/* quotearg.h - quote arguments for output - Copyright (C) 1998, 1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert */ - -/* Basic quoting styles. */ -enum quoting_style - { - literal_quoting_style, /* --quoting-style=literal */ - shell_quoting_style, /* --quoting-style=shell */ - shell_always_quoting_style, /* --quoting-style=shell-always */ - c_quoting_style, /* --quoting-style=c */ - escape_quoting_style, /* --quoting-style=escape */ - locale_quoting_style, /* --quoting-style=locale */ - clocale_quoting_style /* --quoting-style=clocale */ - }; - -/* For now, --quoting-style=literal is the default, but this may change. */ -#ifndef DEFAULT_QUOTING_STYLE -# define DEFAULT_QUOTING_STYLE literal_quoting_style -#endif - -/* Names of quoting styles and their corresponding values. */ -extern char const *const quoting_style_args[]; -extern enum quoting_style const quoting_style_vals[]; - -struct quoting_options; - -#ifndef PARAMS -# if defined PROTOTYPES || defined __STDC__ -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -/* The functions listed below set and use a hidden variable - that contains the default quoting style options. */ - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options *clone_quoting_options - PARAMS ((struct quoting_options *o)); - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style get_quoting_style PARAMS ((struct quoting_options *o)); - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void set_quoting_style PARAMS ((struct quoting_options *o, - enum quoting_style s)); - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int set_char_quoting PARAMS ((struct quoting_options *o, char c, int i)); - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t quotearg_buffer PARAMS ((char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o)); - -/* Use storage slot N to return a quoted version of the string ARG. - Use the default quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. */ -char *quotearg_n PARAMS ((unsigned int n, char const *arg)); - -/* Equivalent to quotearg_n (0, ARG). */ -char *quotearg PARAMS ((char const *arg)); - -/* Use style S and storage slot N to return a quoted version of the string ARG. - This is like quotearg_n (N, ARG), except that it uses S with no other - options to specify the quoting method. */ -char *quotearg_n_style PARAMS ((unsigned int n, enum quoting_style s, - char const *arg)); - -/* Equivalent to quotearg_n_style (0, S, ARG). */ -char *quotearg_style PARAMS ((enum quoting_style s, char const *arg)); - -/* Like quotearg (ARG), except also quote any instances of CH. */ -char *quotearg_char PARAMS ((char const *arg, char ch)); - -/* Equivalent to quotearg_char (ARG, ':'). */ -char *quotearg_colon PARAMS ((char const *arg)); Index: gnu/usr.bin/grep/quotearg.c =================================================================== --- gnu/usr.bin/grep/quotearg.c +++ /dev/null @@ -1,613 +0,0 @@ -/* quotearg.c - quote arguments for output - Copyright (C) 1998, 1999, 2000, 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert */ - -#if HAVE_CONFIG_H -# include -#endif - -#if HAVE_STDDEF_H -# include /* For the definition of size_t on windows w/MSVC. */ -#endif -#include -#include -#include - -#include - -#if ENABLE_NLS -# include -# define _(text) gettext (text) -#else -# define _(text) text -#endif -#define N_(text) text - -#if HAVE_LIMITS_H -# include -#endif -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif -#ifndef UCHAR_MAX -# define UCHAR_MAX ((unsigned char) -1) -#endif - -#if HAVE_C_BACKSLASH_A -# define ALERT_CHAR '\a' -#else -# define ALERT_CHAR '\7' -#endif - -#if HAVE_STDLIB_H -# include -#endif - -#if HAVE_STRING_H -# include -#endif - -#if HAVE_WCHAR_H -# include -#endif - -#if !HAVE_MBRTOWC -/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the - other macros are defined only for documentation and to satisfy C - syntax. */ -# undef MB_CUR_MAX -# define MB_CUR_MAX 1 -# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) -# define mbsinit(ps) 1 -# define iswprint(wc) ISPRINT ((unsigned char) (wc)) -#endif - -#ifndef iswprint -# if HAVE_WCTYPE_H -# include -# endif -# if !defined iswprint && !HAVE_ISWPRINT -# define iswprint(wc) 1 -# endif -#endif - -#define INT_BITS (sizeof (int) * CHAR_BIT) - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) isascii(c) -#endif - -/* Undefine to protect against the definition in wctype.h of solaris2.6. */ -#undef ISPRINT -#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) - -struct quoting_options -{ - /* Basic quoting style. */ - enum quoting_style style; - - /* Quote the characters indicated by this bit vector even if the - quoting style would not normally require them to be quoted. */ - int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; -}; - -/* Names of quoting styles. */ -char const *const quoting_style_args[] = -{ - "literal", - "shell", - "shell-always", - "c", - "escape", - "locale", - "clocale", - 0 -}; - -/* Correspondences to quoting style names. */ -enum quoting_style const quoting_style_vals[] = -{ - literal_quoting_style, - shell_quoting_style, - shell_always_quoting_style, - c_quoting_style, - escape_quoting_style, - locale_quoting_style, - clocale_quoting_style -}; - -/* The default quoting options. */ -static struct quoting_options default_quoting_options; - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options * -clone_quoting_options (struct quoting_options *o) -{ - struct quoting_options *p - = (struct quoting_options *) xmalloc (sizeof (struct quoting_options)); - *p = *(o ? o : &default_quoting_options); - return p; -} - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style -get_quoting_style (struct quoting_options *o) -{ - return (o ? o : &default_quoting_options)->style; -} - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void -set_quoting_style (struct quoting_options *o, enum quoting_style s) -{ - (o ? o : &default_quoting_options)->style = s; -} - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int -set_char_quoting (struct quoting_options *o, char c, int i) -{ - unsigned char uc = c; - int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; - int shift = uc % INT_BITS; - int r = (*p >> shift) & 1; - *p ^= ((i & 1) ^ r) << shift; - return r; -} - -/* MSGID approximates a quotation mark. Return its translation if it - has one; otherwise, return either it or "\"", depending on S. */ -static char const * -gettext_quote (char const *msgid, enum quoting_style s) -{ - char const *translation = _(msgid); - if (translation == msgid && s == clocale_quoting_style) - translation = "\""; - return translation; -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using QUOTING_STYLE and the - non-quoting-style part of O to control quoting. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. - - This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, - ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting - style specified by O, and O may not be null. */ - -static size_t -quotearg_buffer_restyled (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - enum quoting_style quoting_style, - struct quoting_options const *o) -{ - size_t i; - size_t len = 0; - char const *quote_string = 0; - size_t quote_string_len = 0; - int backslash_escapes = 0; - int unibyte_locale = MB_CUR_MAX == 1; - -#define STORE(c) \ - do \ - { \ - if (len < buffersize) \ - buffer[len] = (c); \ - len++; \ - } \ - while (0) - - switch (quoting_style) - { - case c_quoting_style: - STORE ('"'); - backslash_escapes = 1; - quote_string = "\""; - quote_string_len = 1; - break; - - case escape_quoting_style: - backslash_escapes = 1; - break; - - case locale_quoting_style: - case clocale_quoting_style: - { - /* Get translations for open and closing quotation marks. - - The message catalog should translate "`" to a left - quotation mark suitable for the locale, and similarly for - "'". If the catalog has no translation, - locale_quoting_style quotes `like this', and - clocale_quoting_style quotes "like this". - - For example, an American English Unicode locale should - translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and - should translate "'" to U+201D (RIGHT DOUBLE QUOTATION - MARK). A British English Unicode locale should instead - translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and - U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */ - - char const *left = gettext_quote (N_("`"), quoting_style); - char const *right = gettext_quote (N_("'"), quoting_style); - for (quote_string = left; *quote_string; quote_string++) - STORE (*quote_string); - backslash_escapes = 1; - quote_string = right; - quote_string_len = strlen (quote_string); - } - break; - - case shell_always_quoting_style: - STORE ('\''); - quote_string = "'"; - quote_string_len = 1; - break; - - default: - break; - } - - for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++) - { - unsigned char c; - unsigned char esc; - - if (backslash_escapes - && quote_string_len - && i + quote_string_len <= argsize - && memcmp (arg + i, quote_string, quote_string_len) == 0) - STORE ('\\'); - - c = arg[i]; - switch (c) - { - case '?': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case c_quoting_style: - if (i + 2 < argsize && arg[i + 1] == '?') - switch (arg[i + 2]) - { - case '!': case '\'': - case '(': case ')': case '-': case '/': - case '<': case '=': case '>': - /* Escape the second '?' in what would otherwise be - a trigraph. */ - i += 2; - c = arg[i + 2]; - STORE ('?'); - STORE ('\\'); - STORE ('?'); - break; - } - break; - - default: - break; - } - break; - - case ALERT_CHAR: esc = 'a'; goto c_escape; - case '\b': esc = 'b'; goto c_escape; - case '\f': esc = 'f'; goto c_escape; - case '\n': esc = 'n'; goto c_and_shell_escape; - case '\r': esc = 'r'; goto c_and_shell_escape; - case '\t': esc = 't'; goto c_and_shell_escape; - case '\v': esc = 'v'; goto c_escape; - case '\\': esc = c; goto c_and_shell_escape; - - c_and_shell_escape: - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - c_escape: - if (backslash_escapes) - { - c = esc; - goto store_escape; - } - break; - - case '#': case '~': - if (i != 0) - break; - /* Fall through. */ - case ' ': - case '!': /* special in bash */ - case '"': case '$': case '&': - case '(': case ')': case '*': case ';': - case '<': case '>': case '[': - case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ - case '`': case '|': - /* A shell special character. In theory, '$' and '`' could - be the first bytes of multibyte characters, which means - we should check them with mbrtowc, but in practice this - doesn't happen so it's not worth worrying about. */ - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - break; - - case '\'': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case shell_always_quoting_style: - STORE ('\''); - STORE ('\\'); - STORE ('\''); - break; - - default: - break; - } - break; - - case '%': case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case ':': case '=': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': - case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': - case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': - case 'o': case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': - case '{': case '}': - /* These characters don't cause problems, no matter what the - quoting style is. They cannot start multibyte sequences. */ - break; - - default: - /* If we have a multibyte sequence, copy it until we reach - its end, find an error, or come back to the initial shift - state. For C-like styles, if the sequence has - unprintable characters, escape the whole sequence, since - we can't easily escape single characters within it. */ - { - /* Length of multibyte sequence found so far. */ - size_t m; - - int printable; - - if (unibyte_locale) - { - m = 1; - printable = ISPRINT (c); - } - else - { - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); - - m = 0; - printable = 1; - if (argsize == (size_t) -1) - argsize = strlen (arg); - - do - { - wchar_t w; - size_t bytes = mbrtowc (&w, &arg[i + m], - argsize - (i + m), &mbstate); - if (bytes == 0) - break; - else if (bytes == (size_t) -1) - { - printable = 0; - break; - } - else if (bytes == (size_t) -2) - { - printable = 0; - while (i + m < argsize && arg[i + m]) - m++; - break; - } - else - { - if (! iswprint (w)) - printable = 0; - m += bytes; - } - } - while (! mbsinit (&mbstate)); - } - - if (1 < m || (backslash_escapes && ! printable)) - { - /* Output a multibyte sequence, or an escaped - unprintable unibyte character. */ - size_t ilim = i + m; - - for (;;) - { - if (backslash_escapes && ! printable) - { - STORE ('\\'); - STORE ('0' + (c >> 6)); - STORE ('0' + ((c >> 3) & 7)); - c = '0' + (c & 7); - } - if (ilim <= i + 1) - break; - STORE (c); - c = arg[++i]; - } - - goto store_c; - } - } - } - - if (! (backslash_escapes - && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) - goto store_c; - - store_escape: - STORE ('\\'); - - store_c: - STORE (c); - } - - if (quote_string) - for (; *quote_string; quote_string++) - STORE (*quote_string); - - if (len < buffersize) - buffer[len] = '\0'; - return len; - - use_shell_always_quoting_style: - return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - shell_always_quoting_style, o); -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t -quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o) -{ - struct quoting_options const *p = o ? o : &default_quoting_options; - return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - p->style, p); -} - -/* Use storage slot N to return a quoted version of the string ARG. - OPTIONS specifies the quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. N is deliberately declared with type "int" - to allow for future extensions (using negative values). */ -static char * -quotearg_n_options (int n, char const *arg, - struct quoting_options const *options) -{ - /* Preallocate a slot 0 buffer, so that the caller can always quote - one small component of a "memory exhausted" message in slot 0. */ - static char slot0[256]; - static unsigned int nslots = 1; - struct slotvec - { - size_t size; - char *val; - }; - static struct slotvec slotvec0 = {sizeof slot0, slot0}; - static struct slotvec *slotvec = &slotvec0; - - if (nslots <= n) - { - int n1 = n + 1; - size_t s = n1 * sizeof (struct slotvec); - if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) - abort (); - if (slotvec == &slotvec0) - { - slotvec = (struct slotvec *) xmalloc (sizeof (struct slotvec)); - *slotvec = slotvec0; - } - slotvec = (struct slotvec *) xrealloc (slotvec, s); - memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); - nslots = n; - } - - { - size_t size = slotvec[n].size; - char *val = slotvec[n].val; - size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options); - - if (size <= qsize) - { - slotvec[n].size = size = qsize + 1; - slotvec[n].val = val = xrealloc (val == slot0 ? 0 : val, size); - quotearg_buffer (val, size, arg, (size_t) -1, options); - } - - return val; - } -} - -char * -quotearg_n (unsigned int n, char const *arg) -{ - return quotearg_n_options (n, arg, &default_quoting_options); -} - -char * -quotearg (char const *arg) -{ - return quotearg_n (0, arg); -} - -char * -quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg) -{ - struct quoting_options o; - o.style = s; - memset (o.quote_these_too, 0, sizeof o.quote_these_too); - return quotearg_n_options (n, arg, &o); -} - -char * -quotearg_style (enum quoting_style s, char const *arg) -{ - return quotearg_n_style (0, s, arg); -} - -char * -quotearg_char (char const *arg, char ch) -{ - struct quoting_options options; - options = default_quoting_options; - set_char_quoting (&options, ch, 1); - return quotearg_n_options (0, arg, &options); -} - -char * -quotearg_colon (char const *arg) -{ - return quotearg_char (arg, ':'); -} Index: gnu/usr.bin/grep/savedir.h =================================================================== --- gnu/usr.bin/grep/savedir.h +++ /dev/null @@ -1,18 +0,0 @@ -#if !defined SAVEDIR_H_ -# define SAVEDIR_H_ - -#include "exclude.h" - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -extern char * -savedir PARAMS ((const char *dir, off_t name_size, - struct exclude *, struct exclude *)); - -#endif Index: gnu/usr.bin/grep/savedir.c =================================================================== --- gnu/usr.bin/grep/savedir.c +++ /dev/null @@ -1,183 +0,0 @@ -/* savedir.c -- save the list of files in a directory in a string - Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by David MacKenzie . */ - -#include -__FBSDID("$FreeBSD$"); - -#if HAVE_CONFIG_H -# include -#endif - -#include - -#if HAVE_UNISTD_H -# include -#endif - -#if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#ifdef CLOSEDIR_VOID -/* Fake a return value. */ -# define CLOSEDIR(d) (closedir (d), 0) -#else -# define CLOSEDIR(d) closedir (d) -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -char *malloc (); -char *realloc (); -#endif -#ifndef NULL -# define NULL 0 -#endif - -#ifndef stpcpy -char *stpcpy (); -#endif - -#include -#include "savedir.h" -#include "system.h" - -char *path; -size_t pathlen; - -static int -isdir1 (const char *dir, const char *file) -{ - int status; - int slash; - size_t dirlen = strlen (dir); - size_t filelen = strlen (file); - if ((dirlen + filelen + 2) > pathlen) - { - path = calloc (dirlen + 1 + filelen + 1, sizeof (*path)); - pathlen = dirlen + filelen + 2; - } - strcpy (path, dir); - slash = (path[dirlen] != '/'); - path[dirlen] = '/'; - strcpy (path + dirlen + slash , file); - status = isdir (path); - return status; -} - -/* Return a freshly allocated string containing the filenames - in directory DIR, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - NAME_SIZE is the number of bytes to initially allocate - for the string; it will be enlarged as needed. - Return NULL if DIR cannot be opened or if out of memory. */ -char * -savedir (const char *dir, off_t name_size, struct exclude *included_patterns, - struct exclude *excluded_patterns) -{ - DIR *dirp; - struct dirent *dp; - char *name_space; - char *namep; - - dirp = opendir (dir); - if (dirp == NULL) - return NULL; - - /* Be sure name_size is at least `1' so there's room for - the final NUL byte. */ - if (name_size <= 0) - name_size = 1; - - name_space = (char *) malloc (name_size); - if (name_space == NULL) - { - closedir (dirp); - return NULL; - } - namep = name_space; - - while ((dp = readdir (dirp)) != NULL) - { - /* Skip "." and ".." (some NFS filesystems' directories lack them). */ - if (dp->d_name[0] != '.' - || (dp->d_name[1] != '\0' - && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) - { - off_t size_needed = (namep - name_space) + NAMLEN (dp) + 2; - - if ((included_patterns || excluded_patterns) - && !isdir1 (dir, dp->d_name)) - { - if (included_patterns - && !excluded_filename (included_patterns, path, 0)) - continue; - if (excluded_patterns - && excluded_filename (excluded_patterns, path, 0)) - continue; - } - - if (size_needed > name_size) - { - char *new_name_space; - - while (size_needed > name_size) - name_size += 1024; - - new_name_space = realloc (name_space, name_size); - if (new_name_space == NULL) - { - closedir (dirp); - return NULL; - } - namep += new_name_space - name_space; - name_space = new_name_space; - } - namep = stpcpy (namep, dp->d_name) + 1; - } - } - *namep = '\0'; - if (CLOSEDIR (dirp)) - { - free (name_space); - return NULL; - } - if (path) - { - free (path); - path = NULL; - pathlen = 0; - } - return name_space; -} Index: gnu/usr.bin/grep/search.c =================================================================== --- gnu/usr.bin/grep/search.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* search.c - searching subroutines using dfa, kwset and regex for grep. - Copyright 1992, 1998, 2000 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* Written August 1992 by Mike Haertel. */ - -/* $FreeBSD$ */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC -/* We can handle multibyte string. */ -# define MBS_SUPPORT -# include -# include -#endif - -#include "system.h" -#include "grep.h" -#include "regex.h" -#include "dfa.h" -#include "kwset.h" -#include "error.h" -#include "xalloc.h" -#ifdef HAVE_LIBPCRE -# include -#endif -#ifdef HAVE_LANGINFO_CODESET -# include -#endif - -#define NCHAR (UCHAR_MAX + 1) - -/* For -w, we also consider _ to be word constituent. */ -#define WCHAR(C) (ISALNUM(C) || (C) == '_') - -/* DFA compiled regexp. */ -static struct dfa dfa; - -/* The Regex compiled patterns. */ -static struct patterns -{ - /* Regex compiled regexp. */ - struct re_pattern_buffer regexbuf; - struct re_registers regs; /* This is here on account of a BRAIN-DEAD - Q@#%!# library interface in regex.c. */ -} patterns0; - -struct patterns *patterns; -size_t pcount; - -/* KWset compiled pattern. For Ecompile and Gcompile, we compile - a list of strings, at least one of which is known to occur in - any string matching the regexp. */ -static kwset_t kwset; - -/* Number of compiled fixed strings known to exactly match the regexp. - If kwsexec returns < kwset_exact_matches, then we don't need to - call the regexp matcher at all. */ -static int kwset_exact_matches; - -/* UTF-8 encoding allows some optimizations that we can't otherwise - assume in a multibyte encoding. */ -static int using_utf8; - -static void kwsinit PARAMS ((void)); -static void kwsmusts PARAMS ((void)); -static void Gcompile PARAMS ((char const *, size_t)); -static void Ecompile PARAMS ((char const *, size_t)); -static size_t EGexecute PARAMS ((char const *, size_t, size_t *, int )); -static void Fcompile PARAMS ((char const *, size_t)); -static size_t Fexecute PARAMS ((char const *, size_t, size_t *, int)); -static void Pcompile PARAMS ((char const *, size_t )); -static size_t Pexecute PARAMS ((char const *, size_t, size_t *, int)); - -void -check_utf8 (void) -{ -#ifdef HAVE_LANGINFO_CODESET - if (strcmp (nl_langinfo (CODESET), "UTF-8") == 0) - using_utf8 = 1; -#endif -} - -void -dfaerror (char const *mesg) -{ - error (2, 0, mesg); -} - -static void -kwsinit (void) -{ - static char trans[NCHAR]; - size_t i; - - if (match_icase) - for (i = 0; i < NCHAR; ++i) - trans[i] = TOLOWER (i); - - if (!(kwset = kwsalloc (match_icase ? trans : (char *) 0))) - error (2, 0, _("memory exhausted")); -} - -/* If the DFA turns out to have some set of fixed strings one of - which must occur in the match, then we build a kwset matcher - to find those strings, and thus quickly filter out impossible - matches. */ -static void -kwsmusts (void) -{ - struct dfamust const *dm; - char const *err; - - if (dfa.musts) - { - kwsinit (); - /* First, we compile in the substrings known to be exact - matches. The kwset matcher will return the index - of the matching string that it chooses. */ - for (dm = dfa.musts; dm; dm = dm->next) - { - if (!dm->exact) - continue; - ++kwset_exact_matches; - if ((err = kwsincr (kwset, dm->must, strlen (dm->must))) != 0) - error (2, 0, err); - } - /* Now, we compile the substrings that will require - the use of the regexp matcher. */ - for (dm = dfa.musts; dm; dm = dm->next) - { - if (dm->exact) - continue; - if ((err = kwsincr (kwset, dm->must, strlen (dm->must))) != 0) - error (2, 0, err); - } - if ((err = kwsprep (kwset)) != 0) - error (2, 0, err); - } -} - -static void -Gcompile (char const *pattern, size_t size) -{ - const char *err; - char const *sep; - size_t total = size; - char const *motif = pattern; - - check_utf8 (); - re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE | (match_icase ? RE_ICASE : 0)); - dfasyntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase, eolbyte); - - /* For GNU regex compiler we have to pass the patterns separately to detect - errors like "[\nallo\n]\n". The patterns here are "[", "allo" and "]" - GNU regex should have raise a syntax error. The same for backref, where - the backref should have been local to each pattern. */ - do - { - size_t len; - sep = memchr (motif, '\n', total); - if (sep) - { - len = sep - motif; - sep++; - total -= (len + 1); - } - else - { - len = total; - total = 0; - } - - patterns = realloc (patterns, (pcount + 1) * sizeof (*patterns)); - if (patterns == NULL) - error (2, errno, _("memory exhausted")); - - patterns[pcount] = patterns0; - - if ((err = re_compile_pattern (motif, len, - &(patterns[pcount].regexbuf))) != 0) - error (2, 0, err); - pcount++; - - motif = sep; - } while (sep && total != 0); - - /* In the match_words and match_lines cases, we use a different pattern - for the DFA matcher that will quickly throw out cases that won't work. - Then if DFA succeeds we do some hairy stuff using the regex matcher - to decide whether the match should really count. */ - if (match_words || match_lines) - { - /* In the whole-word case, we use the pattern: - \(^\|[^[:alnum:]_]\)\(userpattern\)\([^[:alnum:]_]|$\). - In the whole-line case, we use the pattern: - ^\(userpattern\)$. */ - - static char const line_beg[] = "^\\("; - static char const line_end[] = "\\)$"; - static char const word_beg[] = "\\(^\\|[^[:alnum:]_]\\)\\("; - static char const word_end[] = "\\)\\([^[:alnum:]_]\\|$\\)"; - char *n = xmalloc (sizeof word_beg - 1 + size + sizeof word_end); - size_t i; - strcpy (n, match_lines ? line_beg : word_beg); - i = strlen (n); - memcpy (n + i, pattern, size); - i += size; - strcpy (n + i, match_lines ? line_end : word_end); - i += strlen (n + i); - pattern = n; - size = i; - } - - dfacomp (pattern, size, &dfa, 1); - kwsmusts (); -} - -static void -Ecompile (char const *pattern, size_t size) -{ - const char *err; - const char *sep; - size_t total = size; - char const *motif = pattern; - - check_utf8 (); - if (strcmp (matcher, "awk") == 0) - { - re_set_syntax (RE_SYNTAX_AWK | (match_icase ? RE_ICASE : 0)); - dfasyntax (RE_SYNTAX_AWK, match_icase, eolbyte); - } - else - { - re_set_syntax (RE_SYNTAX_POSIX_EGREP | (match_icase ? RE_ICASE : 0)); - dfasyntax (RE_SYNTAX_POSIX_EGREP, match_icase, eolbyte); - } - - /* For GNU regex compiler we have to pass the patterns separately to detect - errors like "[\nallo\n]\n". The patterns here are "[", "allo" and "]" - GNU regex should have raise a syntax error. The same for backref, where - the backref should have been local to each pattern. */ - do - { - size_t len; - sep = memchr (motif, '\n', total); - if (sep) - { - len = sep - motif; - sep++; - total -= (len + 1); - } - else - { - len = total; - total = 0; - } - - patterns = realloc (patterns, (pcount + 1) * sizeof (*patterns)); - if (patterns == NULL) - error (2, errno, _("memory exhausted")); - patterns[pcount] = patterns0; - - if ((err = re_compile_pattern (motif, len, - &(patterns[pcount].regexbuf))) != 0) - error (2, 0, err); - pcount++; - - motif = sep; - } while (sep && total != 0); - - /* In the match_words and match_lines cases, we use a different pattern - for the DFA matcher that will quickly throw out cases that won't work. - Then if DFA succeeds we do some hairy stuff using the regex matcher - to decide whether the match should really count. */ - if (match_words || match_lines) - { - /* In the whole-word case, we use the pattern: - (^|[^[:alnum:]_])(userpattern)([^[:alnum:]_]|$). - In the whole-line case, we use the pattern: - ^(userpattern)$. */ - - static char const line_beg[] = "^("; - static char const line_end[] = ")$"; - static char const word_beg[] = "(^|[^[:alnum:]_])("; - static char const word_end[] = ")([^[:alnum:]_]|$)"; - char *n = xmalloc (sizeof word_beg - 1 + size + sizeof word_end); - size_t i; - strcpy (n, match_lines ? line_beg : word_beg); - i = strlen(n); - memcpy (n + i, pattern, size); - i += size; - strcpy (n + i, match_lines ? line_end : word_end); - i += strlen (n + i); - pattern = n; - size = i; - } - - dfacomp (pattern, size, &dfa, 1); - kwsmusts (); -} - -static size_t -EGexecute (char const *buf, size_t size, size_t *match_size, int exact) -{ - register char const *buflim, *beg, *end; - char eol = eolbyte; - int backref; - ptrdiff_t start, len; - struct kwsmatch kwsm; - size_t i, ret_val; - static int use_dfa; - static int use_dfa_checked = 0; -#ifdef MBS_SUPPORT - const char *last_char = NULL; - int mb_cur_max = MB_CUR_MAX; - mbstate_t mbs; - memset (&mbs, '\0', sizeof (mbstate_t)); -#endif /* MBS_SUPPORT */ - - if (!use_dfa_checked) - { - char *grep_use_dfa = getenv ("GREP_USE_DFA"); - if (!grep_use_dfa) - { -#ifdef MBS_SUPPORT - /* Turn off DFA when processing multibyte input. */ - use_dfa = (MB_CUR_MAX == 1); -#else - use_dfa = 1; -#endif /* MBS_SUPPORT */ - } - else - { - use_dfa = atoi (grep_use_dfa); - } - - use_dfa_checked = 1; - } - - buflim = buf + size; - - for (beg = end = buf; end < buflim; beg = end) - { - if (!exact) - { - if (kwset) - { - /* Find a possible match using the KWset matcher. */ -#ifdef MBS_SUPPORT - size_t bytes_left = 0; -#endif /* MBS_SUPPORT */ - size_t offset; -#ifdef MBS_SUPPORT - /* kwsexec doesn't work with match_icase and multibyte input. */ - if (match_icase && mb_cur_max > 1) - /* Avoid kwset */ - offset = 0; - else -#endif /* MBS_SUPPORT */ - offset = kwsexec (kwset, beg, buflim - beg, &kwsm); - if (offset == (size_t) -1) - goto failure; -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && !using_utf8) - { - bytes_left = offset; - while (bytes_left) - { - size_t mlen = mbrlen (beg, bytes_left, &mbs); - - last_char = beg; - if (mlen == (size_t) -1 || mlen == 0) - { - /* Incomplete character: treat as single-byte. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - beg++; - bytes_left--; - continue; - } - - if (mlen == (size_t) -2) - { - /* Offset points inside multibyte character: - * no good. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - break; - } - - beg += mlen; - bytes_left -= mlen; - } - } - else -#endif /* MBS_SUPPORT */ - beg += offset; - /* Narrow down to the line containing the candidate, and - run it through DFA. */ - end = memchr(beg, eol, buflim - beg); - end++; -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && bytes_left) - continue; -#endif /* MBS_SUPPORT */ - while (beg > buf && beg[-1] != eol) - --beg; - if ( -#ifdef MBS_SUPPORT - !(match_icase && mb_cur_max > 1) && -#endif /* MBS_SUPPORT */ - (kwsm.index < kwset_exact_matches)) - goto success_in_beg_and_end; - if (use_dfa && - dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1) - continue; - } - else - { - /* No good fixed strings; start with DFA. */ -#ifdef MBS_SUPPORT - size_t bytes_left = 0; -#endif /* MBS_SUPPORT */ - size_t offset = 0; - if (use_dfa) - offset = dfaexec (&dfa, beg, buflim - beg, &backref); - if (offset == (size_t) -1) - break; - /* Narrow down to the line we've found. */ -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && !using_utf8) - { - bytes_left = offset; - while (bytes_left) - { - size_t mlen = mbrlen (beg, bytes_left, &mbs); - - last_char = beg; - if (mlen == (size_t) -1 || mlen == 0) - { - /* Incomplete character: treat as single-byte. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - beg++; - bytes_left--; - continue; - } - - if (mlen == (size_t) -2) - { - /* Offset points inside multibyte character: - * no good. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - break; - } - - beg += mlen; - bytes_left -= mlen; - } - } - else -#endif /* MBS_SUPPORT */ - beg += offset; - end = memchr (beg, eol, buflim - beg); - end++; -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && bytes_left) - continue; -#endif /* MBS_SUPPORT */ - while (beg > buf && beg[-1] != eol) - --beg; - } - /* Successful, no backreferences encountered! */ - if (use_dfa && !backref) - goto success_in_beg_and_end; - } - else - end = beg + size; - - /* If we've made it to this point, this means DFA has seen - a probable match, and we need to run it through Regex. */ - for (i = 0; i < pcount; i++) - { - patterns[i].regexbuf.not_eol = 0; - if (0 <= (start = re_search (&(patterns[i].regexbuf), beg, - end - beg - 1, 0, - end - beg - 1, &(patterns[i].regs)))) - { - len = patterns[i].regs.end[0] - start; - if (exact && !match_words) - goto success_in_start_and_len; - if ((!match_lines && !match_words) - || (match_lines && len == end - beg - 1)) - goto success_in_beg_and_end; - /* If -w, check if the match aligns with word boundaries. - We do this iteratively because: - (a) the line may contain more than one occurence of the - pattern, and - (b) Several alternatives in the pattern might be valid at a - given point, and we may need to consider a shorter one to - find a word boundary. */ - if (match_words) - while (start >= 0) - { - int lword_match = 0; - if (start == 0) - lword_match = 1; - else - { - assert (start > 0); -#ifdef MBS_SUPPORT - if (mb_cur_max > 1) - { - const char *s; - size_t mr; - wchar_t pwc; - - /* Locate the start of the multibyte character - before the match position (== beg + start). */ - if (using_utf8) - { - /* UTF-8 is a special case: scan backwards - until we find a 7-bit character or a - lead byte. */ - s = beg + start - 1; - while (s > buf - && (unsigned char) *s >= 0x80 - && (unsigned char) *s <= 0xbf) - --s; - } - else - { - /* Scan forwards to find the start of the - last complete character before the - match position. */ - size_t bytes_left = start - 1; - s = beg; - while (bytes_left > 0) - { - mr = mbrlen (s, bytes_left, &mbs); - if (mr == (size_t) -1 || mr == 0) - { - memset (&mbs, '\0', sizeof (mbs)); - s++; - bytes_left--; - continue; - } - if (mr == (size_t) -2) - { - memset (&mbs, '\0', sizeof (mbs)); - break; - } - s += mr; - bytes_left -= mr; - } - } - mr = mbrtowc (&pwc, s, beg + start - s, &mbs); - if (mr == (size_t) -2 || mr == (size_t) -1 || - mr == 0) - { - memset (&mbs, '\0', sizeof (mbstate_t)); - lword_match = 1; - } - else if (!(iswalnum (pwc) || pwc == L'_') - && mr == beg + start - s) - lword_match = 1; - } - else -#endif /* MBS_SUPPORT */ - if (!WCHAR ((unsigned char) beg[start - 1])) - lword_match = 1; - } - - if (lword_match) - { - int rword_match = 0; - if (start + len == end - beg - 1) - rword_match = 1; - else - { -#ifdef MBS_SUPPORT - if (mb_cur_max > 1) - { - wchar_t nwc; - int mr; - - mr = mbtowc (&nwc, beg + start + len, - end - beg - start - len - 1); - if (mr <= 0) - { - memset (&mbs, '\0', sizeof (mbstate_t)); - rword_match = 1; - } - else if (!iswalnum (nwc) && nwc != L'_') - rword_match = 1; - } - else -#endif /* MBS_SUPPORT */ - if (!WCHAR ((unsigned char) beg[start + len])) - rword_match = 1; - } - - if (rword_match) - { - if (!exact) - /* Returns the whole line. */ - goto success_in_beg_and_end; - else - /* Returns just this word match. */ - goto success_in_start_and_len; - } - } - if (len > 0) - { - /* Try a shorter length anchored at the same place. */ - --len; - patterns[i].regexbuf.not_eol = 1; - len = re_match (&(patterns[i].regexbuf), beg, - start + len, start, - &(patterns[i].regs)); - } - if (len <= 0) - { - /* Try looking further on. */ - if (start == end - beg - 1) - break; - ++start; - patterns[i].regexbuf.not_eol = 0; - start = re_search (&(patterns[i].regexbuf), beg, - end - beg - 1, - start, end - beg - 1 - start, - &(patterns[i].regs)); - len = patterns[i].regs.end[0] - start; - } - } - } - } /* for Regex patterns. */ - } /* for (beg = end ..) */ - - failure: - return (size_t) -1; - - success_in_beg_and_end: - len = end - beg; - start = beg - buf; - /* FALLTHROUGH */ - - success_in_start_and_len: - *match_size = len; - return start; -} - -#ifdef MBS_SUPPORT -static int f_i_multibyte; /* whether we're using the new -Fi MB method */ -static struct -{ - wchar_t **patterns; - size_t count, maxlen; - unsigned char *match; -} Fimb; -#endif - -static void -Fcompile (char const *pattern, size_t size) -{ - int mb_cur_max = MB_CUR_MAX; - char const *beg, *lim, *err; - - check_utf8 (); -#ifdef MBS_SUPPORT - /* Support -F -i for UTF-8 input. */ - if (match_icase && mb_cur_max > 1) - { - mbstate_t mbs; - wchar_t *wcpattern = xmalloc ((size + 1) * sizeof (wchar_t)); - const char *patternend = pattern; - size_t wcsize; - kwset_t fimb_kwset = NULL; - char *starts = NULL; - wchar_t *wcbeg, *wclim; - size_t allocated = 0; - - memset (&mbs, '\0', sizeof (mbs)); -# ifdef __GNU_LIBRARY__ - wcsize = mbsnrtowcs (wcpattern, &patternend, size, size, &mbs); - if (patternend != pattern + size) - wcsize = (size_t) -1; -# else - { - char *patterncopy = xmalloc (size + 1); - - memcpy (patterncopy, pattern, size); - patterncopy[size] = '\0'; - patternend = patterncopy; - wcsize = mbsrtowcs (wcpattern, &patternend, size, &mbs); - if (patternend != patterncopy + size) - wcsize = (size_t) -1; - free (patterncopy); - } -# endif - if (wcsize + 2 <= 2) - { -fimb_fail: - free (wcpattern); - free (starts); - if (fimb_kwset) - kwsfree (fimb_kwset); - free (Fimb.patterns); - Fimb.patterns = NULL; - } - else - { - if (!(fimb_kwset = kwsalloc (NULL))) - error (2, 0, _("memory exhausted")); - - starts = xmalloc (mb_cur_max * 3); - wcbeg = wcpattern; - do - { - int i; - size_t wclen; - - if (Fimb.count >= allocated) - { - if (allocated == 0) - allocated = 128; - else - allocated *= 2; - Fimb.patterns = xrealloc (Fimb.patterns, - sizeof (wchar_t *) * allocated); - } - Fimb.patterns[Fimb.count++] = wcbeg; - for (wclim = wcbeg; - wclim < wcpattern + wcsize && *wclim != L'\n'; ++wclim) - *wclim = towlower (*wclim); - *wclim = L'\0'; - wclen = wclim - wcbeg; - if (wclen > Fimb.maxlen) - Fimb.maxlen = wclen; - if (wclen > 3) - wclen = 3; - if (wclen == 0) - { - if ((err = kwsincr (fimb_kwset, "", 0)) != 0) - error (2, 0, err); - } - else - for (i = 0; i < (1 << wclen); i++) - { - char *p = starts; - int j, k; - - for (j = 0; j < wclen; ++j) - { - wchar_t wc = wcbeg[j]; - if (i & (1 << j)) - { - wc = towupper (wc); - if (wc == wcbeg[j]) - continue; - } - k = wctomb (p, wc); - if (k <= 0) - goto fimb_fail; - p += k; - } - if ((err = kwsincr (fimb_kwset, starts, p - starts)) != 0) - error (2, 0, err); - } - if (wclim < wcpattern + wcsize) - ++wclim; - wcbeg = wclim; - } - while (wcbeg < wcpattern + wcsize); - f_i_multibyte = 1; - kwset = fimb_kwset; - free (starts); - Fimb.match = xmalloc (Fimb.count); - if ((err = kwsprep (kwset)) != 0) - error (2, 0, err); - return; - } - } -#endif /* MBS_SUPPORT */ - - - kwsinit (); - beg = pattern; - do - { - for (lim = beg; lim < pattern + size && *lim != '\n'; ++lim) - ; - if ((err = kwsincr (kwset, beg, lim - beg)) != 0) - error (2, 0, err); - if (lim < pattern + size) - ++lim; - beg = lim; - } - while (beg < pattern + size); - - if ((err = kwsprep (kwset)) != 0) - error (2, 0, err); -} - -#ifdef MBS_SUPPORT -static int -Fimbexec (const char *buf, size_t size, size_t *plen, int exact) -{ - size_t len, letter, i; - int ret = -1; - mbstate_t mbs; - wchar_t wc; - int patterns_left; - - assert (match_icase && f_i_multibyte == 1); - assert (MB_CUR_MAX > 1); - - memset (&mbs, '\0', sizeof (mbs)); - memset (Fimb.match, '\1', Fimb.count); - letter = len = 0; - patterns_left = 1; - while (patterns_left && len <= size) - { - size_t c; - - patterns_left = 0; - if (len < size) - { - c = mbrtowc (&wc, buf + len, size - len, &mbs); - if (c + 2 <= 2) - return ret; - - wc = towlower (wc); - } - else - { - c = 1; - wc = L'\0'; - } - - for (i = 0; i < Fimb.count; i++) - { - if (Fimb.match[i]) - { - if (Fimb.patterns[i][letter] == L'\0') - { - /* Found a match. */ - *plen = len; - if (!exact && !match_words) - return 0; - else - { - /* For -w or exact look for longest match. */ - ret = 0; - Fimb.match[i] = '\0'; - continue; - } - } - - if (Fimb.patterns[i][letter] == wc) - patterns_left = 1; - else - Fimb.match[i] = '\0'; - } - } - - len += c; - letter++; - } - - return ret; -} -#endif /* MBS_SUPPORT */ - -static size_t -Fexecute (char const *buf, size_t size, size_t *match_size, int exact) -{ - register char const *beg, *try, *end; - register size_t len; - char eol = eolbyte; - struct kwsmatch kwsmatch; - size_t ret_val; -#ifdef MBS_SUPPORT - int mb_cur_max = MB_CUR_MAX; - mbstate_t mbs; - memset (&mbs, '\0', sizeof (mbstate_t)); - const char *last_char = NULL; -#endif /* MBS_SUPPORT */ - - for (beg = buf; beg <= buf + size; ++beg) - { - size_t offset; - offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch); - - if (offset == (size_t) -1) - goto failure; -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && !using_utf8) - { - size_t bytes_left = offset; - while (bytes_left) - { - size_t mlen = mbrlen (beg, bytes_left, &mbs); - - last_char = beg; - if (mlen == (size_t) -1 || mlen == 0) - { - /* Incomplete character: treat as single-byte. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - beg++; - bytes_left--; - continue; - } - - if (mlen == (size_t) -2) - { - /* Offset points inside multibyte character: no good. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - break; - } - - beg += mlen; - bytes_left -= mlen; - } - - if (bytes_left) - { - beg += bytes_left; - continue; - } - } - else -#endif /* MBS_SUPPORT */ - beg += offset; -#ifdef MBS_SUPPORT - /* For f_i_multibyte, the string at beg now matches first 3 chars of - one of the search strings (less if there are shorter search strings). - See if this is a real match. */ - if (f_i_multibyte - && Fimbexec (beg, buf + size - beg, &kwsmatch.size[0], exact)) - goto next_char; -#endif /* MBS_SUPPORT */ - len = kwsmatch.size[0]; - if (exact && !match_words) - goto success_in_beg_and_len; - if (match_lines) - { - if (beg > buf && beg[-1] != eol) - goto next_char; - if (beg + len < buf + size && beg[len] != eol) - goto next_char; - goto success; - } - else if (match_words) - { - while (1) - { - int word_match = 0; - if (beg > buf) - { -#ifdef MBS_SUPPORT - if (mb_cur_max > 1) - { - const char *s; - int mr; - wchar_t pwc; - - if (using_utf8) - { - s = beg - 1; - while (s > buf - && (unsigned char) *s >= 0x80 - && (unsigned char) *s <= 0xbf) - --s; - } - else - s = last_char; - mr = mbtowc (&pwc, s, beg - s); - if (mr <= 0) - memset (&mbs, '\0', sizeof (mbstate_t)); - else if ((iswalnum (pwc) || pwc == L'_') - && mr == (int) (beg - s)) - goto next_char; - } - else -#endif /* MBS_SUPPORT */ - if (WCHAR ((unsigned char) beg[-1])) - goto next_char; - } -#ifdef MBS_SUPPORT - if (mb_cur_max > 1) - { - wchar_t nwc; - int mr; - - mr = mbtowc (&nwc, beg + len, buf + size - beg - len); - if (mr <= 0) - { - memset (&mbs, '\0', sizeof (mbstate_t)); - word_match = 1; - } - else if (!iswalnum (nwc) && nwc != L'_') - word_match = 1; - } - else -#endif /* MBS_SUPPORT */ - if (beg + len >= buf + size || !WCHAR ((unsigned char) beg[len])) - word_match = 1; - if (word_match) - { - if (!exact) - /* Returns the whole line now we know there's a word match. */ - goto success; - else - /* Returns just this word match. */ - goto success_in_beg_and_len; - } - if (len > 0) - { - /* Try a shorter length anchored at the same place. */ - --len; - offset = kwsexec (kwset, beg, len, &kwsmatch); - - if (offset == -1) - goto next_char; /* Try a different anchor. */ -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && !using_utf8) - { - size_t bytes_left = offset; - while (bytes_left) - { - size_t mlen = mbrlen (beg, bytes_left, &mbs); - - last_char = beg; - if (mlen == (size_t) -1 || mlen == 0) - { - /* Incomplete character: treat as single-byte. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - beg++; - bytes_left--; - continue; - } - - if (mlen == (size_t) -2) - { - /* Offset points inside multibyte character: - * no good. */ - memset (&mbs, '\0', sizeof (mbstate_t)); - break; - } - - beg += mlen; - bytes_left -= mlen; - } - - if (bytes_left) - { - memset (&mbs, '\0', sizeof (mbstate_t)); - goto next_char; /* Try a different anchor. */ - } - } - else -#endif /* MBS_SUPPORT */ - beg += offset; -#ifdef MBS_SUPPORT - /* The string at beg now matches first 3 chars of one of - the search strings (less if there are shorter search - strings). See if this is a real match. */ - if (f_i_multibyte - && Fimbexec (beg, len - offset, &kwsmatch.size[0], - exact)) - goto next_char; -#endif /* MBS_SUPPORT */ - len = kwsmatch.size[0]; - } - } - } - else - goto success; -next_char:; -#ifdef MBS_SUPPORT - /* Advance to next character. For MB_CUR_MAX == 1 case this is handled - by ++beg above. */ - if (mb_cur_max > 1) - { - if (using_utf8) - { - unsigned char c = *beg; - if (c >= 0xc2) - { - if (c < 0xe0) - ++beg; - else if (c < 0xf0) - beg += 2; - else if (c < 0xf8) - beg += 3; - else if (c < 0xfc) - beg += 4; - else if (c < 0xfe) - beg += 5; - } - } - else - { - size_t l = mbrlen (beg, buf + size - beg, &mbs); - - last_char = beg; - if (l + 2 >= 2) - beg += l - 1; - else - memset (&mbs, '\0', sizeof (mbstate_t)); - } - } -#endif /* MBS_SUPPORT */ - } - - failure: - return -1; - - success: -#ifdef MBS_SUPPORT - if (mb_cur_max > 1 && !using_utf8) - { - end = beg + len; - while (end < buf + size) - { - size_t mlen = mbrlen (end, buf + size - end, &mbs); - if (mlen == (size_t) -1 || mlen == (size_t) -2 || mlen == 0) - { - memset (&mbs, '\0', sizeof (mbstate_t)); - mlen = 1; - } - if (mlen == 1 && *end == eol) - break; - - end += mlen; - } - } - else -#endif /* MBS_SUPPORT */ - end = memchr (beg + len, eol, (buf + size) - (beg + len)); - - end++; - while (buf < beg && beg[-1] != eol) - --beg; - len = end - beg; - /* FALLTHROUGH */ - - success_in_beg_and_len: - *match_size = len; - return beg - buf; -} - -#if HAVE_LIBPCRE -/* Compiled internal form of a Perl regular expression. */ -static pcre *cre; - -/* Additional information about the pattern. */ -static pcre_extra *extra; -#endif - -static void -Pcompile (char const *pattern, size_t size) -{ -#if !HAVE_LIBPCRE - error (2, 0, _("The -P option is not supported")); -#else - int e; - char const *ep; - char *re = xmalloc (4 * size + 7); - int flags = PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0); - char const *patlim = pattern + size; - char *n = re; - char const *p; - char const *pnul; - - /* FIXME: Remove this restriction. */ - if (eolbyte != '\n') - error (2, 0, _("The -P and -z options cannot be combined")); - - *n = '\0'; - if (match_lines) - strcpy (n, "^("); - if (match_words) - strcpy (n, "\\b("); - n += strlen (n); - - /* The PCRE interface doesn't allow NUL bytes in the pattern, so - replace each NUL byte in the pattern with the four characters - "\000", removing a preceding backslash if there are an odd - number of backslashes before the NUL. - - FIXME: This method does not work with some multibyte character - encodings, notably Shift-JIS, where a multibyte character can end - in a backslash byte. */ - for (p = pattern; (pnul = memchr (p, '\0', patlim - p)); p = pnul + 1) - { - memcpy (n, p, pnul - p); - n += pnul - p; - for (p = pnul; pattern < p && p[-1] == '\\'; p--) - continue; - n -= (pnul - p) & 1; - strcpy (n, "\\000"); - n += 4; - } - - memcpy (n, p, patlim - p); - n += patlim - p; - *n = '\0'; - if (match_words) - strcpy (n, ")\\b"); - if (match_lines) - strcpy (n, ")$"); - - cre = pcre_compile (re, flags, &ep, &e, pcre_maketables ()); - if (!cre) - error (2, 0, ep); - - extra = pcre_study (cre, 0, &ep); - if (ep) - error (2, 0, ep); - - free (re); -#endif -} - -static size_t -Pexecute (char const *buf, size_t size, size_t *match_size, int exact) -{ -#if !HAVE_LIBPCRE - abort (); - return -1; -#else - /* This array must have at least two elements; everything after that - is just for performance improvement in pcre_exec. */ - int sub[300]; - - int e = pcre_exec (cre, extra, buf, size, 0, 0, - sub, sizeof sub / sizeof *sub); - - if (e <= 0) - { - switch (e) - { - case PCRE_ERROR_NOMATCH: - return -1; - - case PCRE_ERROR_NOMEMORY: - error (2, 0, _("Memory exhausted")); - - default: - abort (); - } - } - else - { - /* Narrow down to the line we've found. */ - char const *beg = buf + sub[0]; - char const *end = buf + sub[1]; - char const *buflim = buf + size; - char eol = eolbyte; - if (!exact) - { - end = memchr (end, eol, buflim - end); - end++; - while (buf < beg && beg[-1] != eol) - --beg; - } - - *match_size = end - beg; - return beg - buf; - } -#endif -} - -struct matcher const matchers[] = { - { "default", Gcompile, EGexecute }, - { "grep", Gcompile, EGexecute }, - { "egrep", Ecompile, EGexecute }, - { "awk", Ecompile, EGexecute }, - { "fgrep", Fcompile, Fexecute }, - { "perl", Pcompile, Pexecute }, - { "", 0, 0 }, -}; Index: gnu/usr.bin/grep/system.h =================================================================== --- gnu/usr.bin/grep/system.h +++ /dev/null @@ -1,206 +0,0 @@ -/* Portability cruft. Include after config.h and sys/types.h. - Copyright 1996, 1998, 1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#undef PARAMS -#if defined (__STDC__) && __STDC__ -# ifndef _PTR_T -# define _PTR_T - typedef void * ptr_t; -# endif -# define PARAMS(x) x -#else -# ifndef _PTR_T -# define _PTR_T - typedef char * ptr_t; -# endif -# define PARAMS(x) () -#endif - -#ifdef HAVE_UNISTD_H -# include -# include -#else -# define O_RDONLY 0 -# define SEEK_SET 0 -# define SEEK_CUR 1 -int open(), read(), close(); -#endif - -#include -#ifndef errno -extern int errno; -#endif - -#ifndef HAVE_STRERROR -extern int sys_nerr; -extern char *sys_errlist[]; -# define strerror(E) (0 <= (E) && (E) < sys_nerr ? _(sys_errlist[E]) : _("Unknown system error")) -#endif - -/* Some operating systems treat text and binary files differently. */ -#ifdef __BEOS__ -# undef O_BINARY /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ -#endif -#ifdef HAVE_DOS_FILE_CONTENTS -# include -# ifdef HAVE_SETMODE -# define SET_BINARY(fd) setmode (fd, O_BINARY) -# else -# define SET_BINARY(fd) _setmode (fd, O_BINARY) -# endif -#endif - -#ifdef HAVE_DOS_FILE_NAMES -# define IS_SLASH(c) ((c) == '/' || (c) == '\\') -# define FILESYSTEM_PREFIX_LEN(f) ((f)[0] && (f)[1] == ':' ? 2 : 0) -#endif - -#ifndef IS_SLASH -# define IS_SLASH(c) ((c) == '/') -#endif - -#ifndef FILESYSTEM_PREFIX_LEN -# define FILESYSTEM_PREFIX_LEN(f) 0 -#endif - -int isdir PARAMS ((char const *)); - -#ifdef HAVE_DIR_EACCES_BUG -# ifdef EISDIR -# define is_EISDIR(e, f) \ - ((e) == EISDIR \ - || ((e) == EACCES && isdir (f) && ((e) = EISDIR, 1))) -# else -# define is_EISDIR(e, f) ((e) == EACCES && isdir (f)) -# endif -#endif - -#ifndef is_EISDIR -# ifdef EISDIR -# define is_EISDIR(e, f) ((e) == EISDIR) -# else -# define is_EISDIR(e, f) 0 -# endif -#endif - -#if STAT_MACROS_BROKEN -# undef S_ISDIR -# undef S_ISREG -#endif -#if !defined(S_ISDIR) && defined(S_IFDIR) -# define S_ISDIR(Mode) (((Mode) & S_IFMT) == S_IFDIR) -#endif -#if !defined(S_ISREG) && defined(S_IFREG) -# define S_ISREG(Mode) (((Mode) & S_IFMT) == S_IFREG) -#endif - -#ifdef STDC_HEADERS -# include -#else -char *getenv (); -ptr_t malloc(), realloc(), calloc(); -void free(); -#endif - -#if __STDC__ -# include -#endif -#ifdef STDC_HEADERS -# include -#endif -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif -/* The extra casts work around common compiler bugs. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ - ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \ - : (t) 0)) -#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t))) -#ifndef CHAR_MAX -# define CHAR_MAX TYPE_MAXIMUM (char) -#endif -#ifndef INT_MAX -# define INT_MAX TYPE_MAXIMUM (int) -#endif -#ifndef UCHAR_MAX -# define UCHAR_MAX TYPE_MAXIMUM (unsigned char) -#endif - -#if !defined(STDC_HEADERS) && defined(HAVE_STRING_H) && defined(HAVE_MEMORY_H) -# include -#endif -#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) -# include -#else -# include -# undef strchr -# define strchr index -# undef strrchr -# define strrchr rindex -# undef memcpy -# define memcpy(d, s, n) bcopy (s, d, n) -#endif -#ifndef HAVE_MEMCHR -ptr_t memchr(); -#endif -#if ! defined HAVE_MEMMOVE && ! defined memmove -# define memmove(d, s, n) bcopy (s, d, n) -#endif - -#include - -#ifndef isgraph -# define isgraph(C) (isprint(C) && !isspace(C)) -#endif - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) isascii(c) -#endif - -#define ISALPHA(C) (IN_CTYPE_DOMAIN (C) && isalpha (C)) -#define ISUPPER(C) (IN_CTYPE_DOMAIN (C) && isupper (C)) -#define ISLOWER(C) (IN_CTYPE_DOMAIN (C) && islower (C)) -#define ISDIGIT(C) (IN_CTYPE_DOMAIN (C) && isdigit (C)) -#define ISXDIGIT(C) (IN_CTYPE_DOMAIN (C) && isxdigit (C)) -#define ISSPACE(C) (IN_CTYPE_DOMAIN (C) && isspace (C)) -#define ISPUNCT(C) (IN_CTYPE_DOMAIN (C) && ispunct (C)) -#define ISALNUM(C) (IN_CTYPE_DOMAIN (C) && isalnum (C)) -#define ISPRINT(C) (IN_CTYPE_DOMAIN (C) && isprint (C)) -#define ISGRAPH(C) (IN_CTYPE_DOMAIN (C) && isgraph (C)) -#define ISCNTRL(C) (IN_CTYPE_DOMAIN (C) && iscntrl (C)) - -#define TOLOWER(C) (ISUPPER(C) ? tolower(C) : (C)) - -#if ENABLE_NLS -# include -# define _(String) gettext (String) -#else -# define _(String) String -#endif -#define N_(String) String - -#if HAVE_SETLOCALE -# include -#endif - -#ifndef initialize_main -#define initialize_main(argcp, argvp) -#endif Index: gnu/usr.bin/grep/tests/backref.sh =================================================================== --- gnu/usr.bin/grep/tests/backref.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# Test that backrefs are local to regex. -# -# - -: ${srcdir=.} - -failures=0 - -# checking for a palindrome -echo "radar" | ${GREP} -e '\(.\)\(.\).\2\1' > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "backref: palindrome, test \#1 failed" - failures=1 -fi - -# hit hard with the `Bond' tests -echo "civic" | ${GREP} -E -e '^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1$' > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "Options: Bond, test \#2 failed" - failures=1 -fi - -# backref are local should be error -echo "123" | ${GREP} -e 'a\(.\)' -e 'b\1' > /dev/null 2>&1 -if test $? -ne 2 ; then - echo "Options: Backref not local, test \#3 failed" - failures=1 -fi - -# Pattern should faile -echo "123" | ${GREP} -e '[' -e ']' > /dev/null 2>&1 -if test $? -ne 2 ; then - echo "Options: Compiled not local, test \#3 failed" - failures=1 -fi - -exit $failures Index: gnu/usr.bin/grep/tests/bre.awk =================================================================== --- gnu/usr.bin/grep/tests/bre.awk +++ /dev/null @@ -1,27 +0,0 @@ -BEGIN { - FS="@"; - n = 0; - printf ("# Generated Spencer BRE Test\n"); - printf ("failures=0\n"); -} - -$0 ~ /^#/ { next; } - -NF == 3 { -# printf ("status=`echo '%s' | { ${GREP} -e '%s' > /dev/null 2>&1; echo $?; cat >/dev/null; }`\n",$3, $2); - printf ("status=`echo '%s' | { ${GREP} -e '%s' > /dev/null 2>&1; echo $? ; }`\n",$3, $2); - printf ("if test $status -ne %s ; then\n", $1); - printf ("\techo Spencer bre test \\#%d failed\n", ++n); - printf ("\tfailures=1\n"); - printf ("fi\n"); -} - -NF == 4 { -#don't alarm users -# printf ("echo '%s' | ${GREP} -e '%s' > /dev/null 2>&1\n",$3, $2); -# printf ("if test $? -ne %s ; then\n", $1); -# printf ("\techo Expected non conformance \\#%d ... continuing\n", ++n); -# printf ("fi\n"); -} - -END { printf ("exit $failures\n"); } Index: gnu/usr.bin/grep/tests/bre.sh =================================================================== --- gnu/usr.bin/grep/tests/bre.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Regression test for GNU grep. - -: ${srcdir=.} - -failures=0 - -# . . . and the following by Henry Spencer. - -${AWK-awk} -f $srcdir/bre.awk $srcdir/bre.tests > bre.script - -sh bre.script && exit $failures -exit 1 Index: gnu/usr.bin/grep/tests/bre.tests =================================================================== --- gnu/usr.bin/grep/tests/bre.tests +++ /dev/null @@ -1,62 +0,0 @@ -0@a\(b\)c@abc -0@a(@a( -2@a\(@EPAREN -2@a\(b@EPAREN -0@a(b@a(b -0@a)@a) -2@a\)@EPAREN -2@\)@EPAREN -0@a\(\)b@ab -0@a^b@a^b@TO CORRECT -0@a$b@a$b -0@\($\)\(^\)@@ -0@a*\(^b$\)c*@b -0@|@| -0@*@* -0@\(\)@abc -2@\(\{1\}a\)@BADRPT@TO CORRECT -0@^*@* -2@^\{1\}@BADRPT@TO CORRECT -0@{@{ -1@a\(b*\)c\1d@abbcbd -1@a\(b*\)c\1d@abbcbbbd -1@^\(.\)\1@abc -0@a\(\([bc]\)\2\)*d@abbccd -1@a\(\([bc]\)\2\)*d@abbcbd -0@a\(\(b\)*\2\)*d@abbbd -0@\(a\)\1bcd@aabcd -0@\(a\)\1bc*d@aabcd -0@\(a\)\1bc*d@aabd -0@\(a\)\1bc*d@aabcccd -0@\(a\)\1bc*[ce]d@aabcccd@TO CORRECT -0@^\(a\)\1b\(c\)*cd$@aabcccd -0@a\(*\)b@a*b -0@a\(**\)b@ab -2@a\(***\)b@BADRPT@TO CORRECT -0@*a@*a -0@**a@a -2@***a@BADRPT@TO CORRECT -0@a\{1\}b@ab -0@a\{1,\}b@ab -0@a\{1,2\}b@aab -2@a\{1@EBRACE -2@a\{1a@EBRACE -2@a\{1a\}@BADBR -2@a\{,2\}@BADBR -2@a\{,\}@BADBR -2@a\{1,x\}@BADBR -2@a\{1,x@EBRACE -2@a\{32768\}@BADBR -2@a\{1,0\}@BADBR -0@ab\{0,0\}c@abcac -0@ab\{0,1\}c@abcac -0@ab\{0,3\}c@abbcac -0@ab\{1,1\}c@acabc -0@ab\{1,3\}c@acabc -0@ab\{2,2\}c@abcabbc -0@ab\{2,4\}c@abcabbc -2@a\{1\}\{1\}@BADRPT@TO CORRECT -2@a*\{1\}@BADRPT@TO CORRECT -2@a\{1\}*@BADRPT@TO CORRECT -1@a\(b\)?c\1d@acd -0@-\{0,1\}[0-9]*$@-5 Index: gnu/usr.bin/grep/tests/empty.sh =================================================================== --- gnu/usr.bin/grep/tests/empty.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -# test that the empty file means no pattern -# and an empty pattern means match all. - -: ${srcdir=.} - -failures=0 - -for options in '-E' '-E -w' '-F -x' '-G -w -x'; do - - # should return 0 found a match - echo "" | ${GREP} $options -e '' > /dev/null 2>&1 - if test $? -ne 0 ; then - echo "Status: Wrong status code, test \#1 failed ($options)" - failures=1 - fi - - # should return 1 found no match - echo "abcd" | ${GREP} $options -f /dev/null > /dev/null 2>&1 - if test $? -ne 1 ; then - echo "Status: Wrong status code, test \#2 failed ($options)" - failures=1 - fi - - # should return 0 found a match - echo "abcd" | ${GREP} $options -f /dev/null -e "abcd" > /dev/null 2>&1 - if test $? -ne 0 ; then - echo "Status: Wrong status code, test \#3 failed ($options)" - failures=1 - fi -done - -exit $failures Index: gnu/usr.bin/grep/tests/ere.awk =================================================================== --- gnu/usr.bin/grep/tests/ere.awk +++ /dev/null @@ -1,32 +0,0 @@ -BEGIN { - FS="@"; - n = 0; - printf ("# Generated Spencer ERE Test\n"); - printf ("failures=0\n"); -} - -$0 ~ /^#/ { next; } - -NF == 3 { -# printf ("status=`echo '%s' | { ${GREP} -E -e '%s' > /dev/null 2>&1; echo $?; cat >/dev/null; }`\n",$3, $2); - printf ("status=`echo '%s' | { ${GREP} -E -e '%s' > /dev/null 2>&1; echo $?; }`\n",$3, $2); - printf ("if test $status -ne %s ; then\n", $1); - printf ("\techo Spencer ere test \\#%d failed\n", ++n); - printf ("\tfailures=1\n"); - printf ("fi\n"); -} - -NF == 4 { -# don't alarm the user for now -# printf ("echo '%s'|${GREP} -E -e '%s' > /dev/null 2>&1\n",$3, $2); -# printf ("if test $? -ne %s ; then\n", $1); -# printf ("\techo Expected non conformance \\#%d ... continuing\n", ++n); -# printf ("fi\n"); -} - -NF == 5 { -# don't alarm the user for now - next; -} - -END { printf ("exit $failures\n"); } Index: gnu/usr.bin/grep/tests/ere.sh =================================================================== --- gnu/usr.bin/grep/tests/ere.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Regression test for GNU grep. - -: ${srcdir=.} - -failures=0 - -# . . . and the following by Henry Spencer. - -${AWK-awk} -f $srcdir/ere.awk $srcdir/ere.tests > ere.script - -sh ere.script && exit $failures -exit 1 Index: gnu/usr.bin/grep/tests/ere.tests =================================================================== --- gnu/usr.bin/grep/tests/ere.tests +++ /dev/null @@ -1,215 +0,0 @@ -0@a@a -0@abc@abc -0@abc|de@abc -0@a|b|c@abc -0@a(b)c@abc -2@a(@EPAREN -0@a\(@a( -2@a(b@EPAREN -0@a)@a)@POSIX BOTCH -0@)@)@POSIX BOTCH -0@a()b@ab -0@^abc$@abc -1@a^b@a^b -1@a$b@a$b -0@^@abc -0@$@abc -0@^$@@ -0@$^@@ -0@^^@@ -0@$$@@ -0@a*(^b$)c*@b -2@|@EMPTY@NO ALTERNATION -2@*@BADRPT@TO CORRECT -2@+@BADRPT@TO CORRECT -2@?@BADRPT@TO CORRECT -1@&C@PASS -0@()@abc -2@a||b@EMPTY@NO ALTERNATION -2@|ab@EMPTY@NO ALTERNATION -2@ab|@EMPTY@NO ALTERNATION -2@(|a)b@EMPTY@NO ALTERNATION -2@(a|)b@EMPTY@NO ALTERNATION -2@(*a)@BADRPT@TO CORRECT -2@(+a)@BADRPT@TO CORRECT -2@(?a)@BADRPT@TO CORRECT -2@({1}a)@BADRPT@TO CORRECT -2@(a|*b)@BADRPT@NO ALTERNATION -2@(a|+b)@BADRPT@NO ALTERNATION -2@(a|?b)@BADRPT@NO ALTERNATION -2@(a|{1}b)@BADRPT@NO ALTERNATION -2@^*@BADRPT@TO CORRECT -2@^+@BADRPT@TO CORRECT -2@^?@BADRPT@TO CORRECT -2@^{1}@BADRPT@TO CORRECT -0@a.c@abc -0@a[bc]d@abd -0@a\*c@a*c -0@a\\b@a\b@TO CORRECT -0@a\\\*b@a\*b@SHELL TROUBLE -0@a\bc@abc@TO CORRECT -2@a\@EESCAPE@SHELL TROUBLE -0@a\\bc@a\bc@TO CORRECT -0@a\[b@a[b -2@a[b@EBRACK -0@a$@a -1@a$@a$ -1@a\$@a@SHELL TROUBLE -0@a\$@a$@SHELL TROUBLE -1@a\\$@a -1@a\\$@a$@SHELL TROUBLE -1@a\\$@a\$@SHELL TROUBLE -0@a\\$@a\@SHEL TROUBLE -0@ab*c@abc -0@ab+c@abc -0@ab?c@abc -0@{@{@TO CORRECT -0@{abc@{abc@TO CORRECT -0@{1@{1 -2@{1}@BADRPT@TO CORRECT -0@a{b@a{b@TO CORRECT -0@a{1}b@ab -0@a{1,}b@ab -0@a{1,2}b@aab -0@a{1@a{1 -1@a{1a@aa -0@a{1a}@a{1a} -0@a{,2}@a{,2} -0@a{,}@a{,} -0@a{1,*}@a{1,,,} -2@a{1,x@EBRACE@TO CORRECT -2@a{300}@BADBR@TO CORRECT -2@a{1,0}@BADBR@TO CORRECT -0@ab{0,0}c@abcac -0@ab{0,1}c@abcac -0@ab{0,3}c@abbcac -0@ab{1,1}c@acabc -0@ab{1,3}c@acabc -0@ab{2,2}c@abcabbc -0@ab{2,4}c@abcabbc -2@a**@BADRPT@TO CORRECT -2@a++@BADRPT@TO CORRECT -2@a??@BADRPT@TO CORRECT -2@a*+@BADRPT@TO CORRECT -2@a*?@BADRPT@TO CORRECT -2@a+*@BADRPT@TO CORRECT -2@a+?@BADRPT@TO CORRECT -2@a?*@BADRPT@TO CORRECT -2@a?+@BADRPT@TO CORRECT -2@a{1}{1}@BADRPT@TO CORRECT -2@a*{1}@BADRPT@TO CORRECT -2@a+{1}@BADRPT@TO CORRECT -2@a?{1}@BADRPT@TO CORRECT -2@a{1}*@BADRPT@TO CORRECT -2@a{1}+@BADRPT@TO CORRECT -2@a{1}?@BADRPT@TO CORRECT -0@a*{b}@a{b}@TO CORRECT -0@a[b]c@abc -0@a[ab]c@abc -0@a[^ab]c@adc -0@a[]b]c@a]c -0@a[[b]c@a[c -0@a[-b]c@a-c -0@a[^]b]c@adc -0@a[^-b]c@adc -0@a[b-]c@a-c -2@a[b@EBRACK -2@a[]@EBRACK -0@a[1-3]c@a2c -2@a[3-1]c@ERANGE@TO CORRECT -2@a[1-3-5]c@ERANGE@TO CORRECT -0@a[[.-.]--]c@a-c@TO CORRECT -2@a[1-@ERANGE -2@a[[.@EBRACK -2@a[[.x@EBRACK -2@a[[.x.@EBRACK -2@a[[.x.]@EBRACK@TO CORRECT -0@a[[.x.]]@ax@TO CORRECT -2@a[[.x,.]]@ECOLLATE@TO CORRECT -0@a[[.one.]]b@a1b@TO CORRECT -2@a[[.notdef.]]b@ECOLLATE@TO CORRECT -0@a[[.].]]b@a]b@TO CORRECT -0@a[[:alpha:]]c@abc -2@a[[:notdef:]]c@ECTYPE -2@a[[:@EBRACK -2@a[[:alpha@EBRACK -2@a[[:alpha:]@EBRACK -2@a[[:alpha,:]@ECTYPE -2@a[[:]:]]b@ECTYPE -2@a[[:-:]]b@ECTYPE -2@a[[:alph:]]@ECTYPE -2@a[[:alphabet:]]@ECTYPE -0@[[:digit:]]+@a019b -0@[[:lower:]]+@AabC -0@[[:upper:]]+@aBCd -0@[[:xdigit:]]+@p0f3Cq -0@a[[=b=]]c@abc@TO CORRECT -2@a[[=@EBRACK -2@a[[=b@EBRACK -2@a[[=b=@EBRACK -2@a[[=b=]@EBRACK@TO CORRECT -2@a[[=b,=]]@ECOLLATE@TO CORRECT -0@a[[=one=]]b@a1b@TO CORRECT -0@a(((b)))c@abc -0@a(b|(c))d@abd -0@a(b*|c)d@abbd -0@a[ab]{20}@aaaaabaaaabaaaabaaaab -0@a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab]@aaaaabaaaabaaaabaaaab -0@a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night)@aaaaabaaaabaaaabaaaabweeknights -0@12345678901234567890123456789@a12345678901234567890123456789b -0@123456789012345678901234567890@a123456789012345678901234567890b -0@1234567890123456789012345678901@a1234567890123456789012345678901b -0@12345678901234567890123456789012@a12345678901234567890123456789012b -0@123456789012345678901234567890123@a123456789012345678901234567890123b -0@1234567890123456789012345678901234567890123456789012345678901234567890@a1234567890123456789012345678901234567890123456789012345678901234567890b -0@[ab][cd][ef][gh][ij][kl][mn]@xacegikmoq -0@[ab][cd][ef][gh][ij][kl][mn][op]@xacegikmoq -0@[ab][cd][ef][gh][ij][kl][mn][op][qr]@xacegikmoqy -0@[ab][cd][ef][gh][ij][kl][mn][op][q]@xacegikmoqy -0@abc@xabcy -0@aBc@Abc@TO CORRECT -0@a[Bc]*d@abBCcd@TO CORRECT -0@0[[:upper:]]1@0a1@TO CORRECT -0@0[[:lower:]]1@0A1@TO CORRECT -1@a[^b]c@abc -1@a[^b]c@aBc@TO CORRECT -0@a[^b]c@adc -0@[a]b[c]@abc -0@[a]b[a]@aba -0@[abc]b[abc]@abc -0@[abc]b[abd]@abd -0@a(b?c)+d@accd -0@(wee|week)(knights|night)@weeknights -0@(we|wee|week|frob)(knights|night|day)@weeknights -0@a[bc]d@xyzaaabcaababdacd -0@a[ab]c@aaabc -0@a*@b -0@/\*.*\*/@/*x*/ -0@/\*.*\*/@/*x*/y/*z*/ -0@/\*([^*]|\*[^/])*\*/@/*x*/ -0@/\*([^*]|\*[^/])*\*/@/*x*/y/*z*/ -0@/\*([^*]|\*[^/])*\*/@/*x**/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x*/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x**/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x****/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x**x*/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x***x/y/*z*/ -0@aZb@a@TO CORRECT -0@[[:<:]]a@a@TO CORRECT -1@[[:<:]]a@ba@TO CORRECT -0@[[:<:]]a@-a@TO CORRECT -0@a[[:>:]]@a@TO CORRECT -1@a[[:>:]]@ab@TO CORRECT -0@a[[:>:]]@a-@TO CORRECT -0@[[:<:]]a.c[[:>:]]@axcd-dayc-dazce-abc@TO CORRECT -0@[[:<:]]a.c[[:>:]]@axcd-dayc-dazce-abc-q@TO CORRECT -0@[[:<:]]a.c[[:>:]]@axc-dayc-dazce-abc@TO CORRECT -0@[[:<:]]b.c[[:>:]]@a_bxc-byc_d-bzc-q@TO CORRECT -0@[[:<:]].x..[[:>:]]@y_xa_-_xb_y-_xc_-axdc@TO CORRECT -1@[[:<:]]a_b[[:>:]]@x_a_b@TO CORRECT -0@(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A])@A1 -0@abcdefghijklmnop@abcdefghijklmnop -0@abcdefghijklmnopqrstuv@abcdefghijklmnopqrstuv -0@CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a@CC11 -0@a?b@ab Index: gnu/usr.bin/grep/tests/file.sh =================================================================== --- gnu/usr.bin/grep/tests/file.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -# Test for POSIX.2 options for grep -# -# grep -E -f pattern_file file -# grep -F -f pattern_file file -# grep -G -f pattern_file file -# - -: ${srcdir=.} - -failures=0 - -cat <patfile -radar -MILES -GNU -EOF - -# match -echo "miles" | ${GREP} -i -E -f patfile > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "File_pattern: Wrong status code, test \#1 failed" - failures=1 -fi - -# match -echo "GNU" | ${GREP} -G -f patfile > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "File_pattern: Wrong status code, test \#2 failed" - failures=1 -fi - -# checking for no match -echo "ridar" | ${GREP} -F -f patfile > /dev/null 2>&1 -if test $? -ne 1 ; then - echo "File_pattern: Wrong status code, test \#3 failed" - failures=1 -fi - -cat <patfile - -EOF -# empty pattern : every match -echo "abbcd" | ${GREP} -F -f patfile > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "File_pattern: Wrong status code, test \#4 failed" - failures=1 -fi - -cp /dev/null patfile - -# null pattern : no match -echo "abbcd" | ${GREP} -F -f patfile > /dev/null 2>&1 -if test $? -ne 1 ; then - echo "File_pattern: Wrong status code, test \#5 failed" - failures=1 -fi - -exit $failures Index: gnu/usr.bin/grep/tests/formatbre.awk =================================================================== --- gnu/usr.bin/grep/tests/formatbre.awk +++ /dev/null @@ -1,55 +0,0 @@ -# -# Basic Regular Expression - -# kip comments -$0 ~ /^#/ { next; } - -# skip those option specific to regexec/regcomp -$2 ~ /[msnr$#p^]/ { next; } - -# skip empty lines -$0 ~ /^$/ { next; } - -# debug -#{ printf ("<%s> <%s> <%s> <%s>\n", $1, $2, $3, $4); } - -# subreg expresion -NF >= 5 { next; } - -# errors -NF == 3 { -# gsub (/@/, ","); -# it means empty lines - gsub (/\"\"/, ""); -# escapes - gsub (/\\\'/, "\\\'\'"); -# error in regex - if (index ($2, "C") != 0) - { - if (index ($2, "b") != 0) - printf ("2@%s@%s\n", $1, $3); - } -# erro no match - else - { - if (index ($2, "b") != 0) - printf ("1@%s@%s\n", $1, $3); - } - next; -} - -# ok -NF == 4 { -# skip those magic cookies can't rely on echo to gnerate them - if (match($3, /[NSTZ]/)) - next; - -# gsub (/@/, ","); -# it means empty lines - gsub (/\"\"/, ""); -# escape escapes - gsub (/\\\'/, "\\\'\'"); - - if (index ($2, "b") != 0) - printf ("0@%s@%s\n", $1, $3); -} Index: gnu/usr.bin/grep/tests/formatere.awk =================================================================== --- gnu/usr.bin/grep/tests/formatere.awk +++ /dev/null @@ -1,60 +0,0 @@ -# -# Extended Regular Expression - -# skip comments -$0 ~ /^#/ { next; } - -# skip specifics to regcomp/regexec -$2 ~ /[msnr$#p^]/ { next; } - -# jump empty lines -$0 ~ /^$/ { next; } - -# subreg skip -NF >= 5 { next; } - -# debug -#{ printf ("<%s> <%s> <%s> <%s>\n", $1, $2, $3, $4); } - -# errors -NF == 3 { -# nuke any remaining '@' -# gsub (/@/, ","); -# it means empty lines - gsub (/\"\"/, ""); -# escapes - gsub (/\\\'/, "\\\'\'"); -# error in regex - if (index ($2, "C") != 0) - { - if (index ($2, "b") == 0) - printf ("2@%s@%s\n", $1, $3); - } -# error not matching - else - { - if (index ($2, "b") == 0) - printf ("1@%s@%s\n", $1, $3); - } - next; -} - -# ok -NF == 4 { -# skip those magic cookies can't rely on echo to gnerate them - if (match($3, /[NSTZ]/)) - next; - -# nuke any remaining '@' -# gsub (/@/, ","); -# it means empty lines - gsub (/\"\"/, ""); -# escape escapes - gsub (/\\\'/, "\\\'\'"); - - if (index ($2, "b") == 0) - { - printf ("0@%s@%s\n", $1, $3); - } - next; -} Index: gnu/usr.bin/grep/tests/khadafy.lines =================================================================== --- gnu/usr.bin/grep/tests/khadafy.lines +++ /dev/null @@ -1,32 +0,0 @@ -1) Muammar Qaddafi -2) Mo'ammar Gadhafi -3) Muammar Kaddafi -4) Muammar Qadhafi -5) Moammar El Kadhafi -6) Muammar Gadafi -7) Mu'ammar al-Qadafi -8) Moamer El Kazzafi -9) Moamar al-Gaddafi -10) Mu'ammar Al Qathafi -11) Muammar Al Qathafi -12) Mo'ammar el-Gadhafi -13) Moamar El Kadhafi -14) Muammar al-Qadhafi -15) Mu'ammar al-Qadhdhafi -16) Mu'ammar Qadafi -17) Moamar Gaddafi -18) Mu'ammar Qadhdhafi -19) Muammar Khaddafi -20) Muammar al-Khaddafi -21) Mu'amar al-Kadafi -22) Muammar Ghaddafy -23) Muammar Ghadafi -24) Muammar Ghaddafi -25) Muamar Kaddafi -26) Muammar Quathafi -27) Muammar Gheddafi -28) Muamar Al-Kaddafi -29) Moammar Khadafy -30) Moammar Qudhafi -31) Mu'ammar al-Qaddafi -32) Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi Index: gnu/usr.bin/grep/tests/khadafy.regexp =================================================================== --- gnu/usr.bin/grep/tests/khadafy.regexp +++ /dev/null @@ -1 +0,0 @@ -M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Index: gnu/usr.bin/grep/tests/khadafy.sh =================================================================== --- gnu/usr.bin/grep/tests/khadafy.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Regression test for GNU grep. - -: ${srcdir=.} -: ${GREP=../src/grep} - -failures=0 - -# The Khadafy test is brought to you by Scott Anderson . . . - -${GREP} -E -f $srcdir/khadafy.regexp $srcdir/khadafy.lines > khadafy.out -if cmp $srcdir/khadafy.lines khadafy.out -then - : -else - echo Khadafy test failed -- output left on khadafy.out - failures=1 -fi - -exit $failures Index: gnu/usr.bin/grep/tests/options.sh =================================================================== --- gnu/usr.bin/grep/tests/options.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# Test for POSIX.2 options for grep -# -# grep [ -E| -F][ -c| -l| -q ][-insvx] -e pattern_list -# [-f pattern_file] ... [file. ..] -# grep [ -E| -F][ -c| -l| -q ][-insvx][-e pattern_list] -# -f pattern_file ... [file ...] -# grep [ -E| -F][ -c| -l| -q ][-insvx] pattern_list [file...] -# - -: ${srcdir=.} - -failures=0 - -# checking for -E extended regex -echo "abababccccccd" | ${GREP} -E -e 'c{3}' > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "Options: Wrong status code, test \#1 failed" - failures=1 -fi - -# checking for basic regex -echo "abababccccccd" | ${GREP} -G -e 'c\{3\}' > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "Options: Wrong status code, test \#2 failed" - failures=1 -fi - -# checking for fixed string -echo "abababccccccd" | ${GREP} -F -e 'c\{3\}' > /dev/null 2>&1 -if test $? -ne 1 ; then - echo "Options: Wrong status code, test \#3 failed" - failures=1 -fi - -exit $failures Index: gnu/usr.bin/grep/tests/spencer1.awk =================================================================== --- gnu/usr.bin/grep/tests/spencer1.awk +++ /dev/null @@ -1,15 +0,0 @@ -BEGIN { - FS = "@"; - printf ("failures=0\n"); -} - -$0 !~ /^#/ && NF = 3 { -# printf ("status=`echo '%s'| { ${GREP} -E -e '%s' > /dev/null 2>&1; echo $?; cat >/dev/null; }`\n",$3, $2); - printf ("status=`echo '%s'| { ${GREP} -E -e '%s' >/dev/null 2>&1 ; echo $?; }`\n",$3, $2); - printf ("if test $status -ne %s ; then\n", $1); - printf ("\techo Spencer test \\#%d failed\n", ++n); - printf ("\tfailures=1\n"); - printf ("fi\n"); -} - -END { printf ("exit $failures\n"); } Index: gnu/usr.bin/grep/tests/spencer1.sh =================================================================== --- gnu/usr.bin/grep/tests/spencer1.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Regression test for GNU grep. - -: ${srcdir=.} - -failures=0 - -# . . . and the following by Henry Spencer. - -${AWK-awk} -f $srcdir/spencer1.awk $srcdir/spencer1.tests > spencer1.script - -sh spencer1.script && exit $failures -exit 1 Index: gnu/usr.bin/grep/tests/spencer1.tests =================================================================== --- gnu/usr.bin/grep/tests/spencer1.tests +++ /dev/null @@ -1,122 +0,0 @@ -0@abc@abc -1@abc@xbc -1@abc@axc -1@abc@abx -0@abc@xabcy -0@abc@ababc -0@ab*c@abc -0@ab*bc@abc -0@ab*bc@abbc -0@ab*bc@abbbbc -0@ab+bc@abbc -1@ab+bc@abc -1@ab+bc@abq -0@ab+bc@abbbbc -0@ab?bc@abbc -0@ab?bc@abc -1@ab?bc@abbbbc -0@ab?c@abc -0@^abc$@abc -1@^abc$@abcc -0@^abc@abcc -1@^abc$@aabc -0@abc$@aabc -0@^@abc -0@$@abc -0@a.c@abc -0@a.c@axc -0@a.*c@axyzc -1@a.*c@axyzd -1@a[bc]d@abc -0@a[bc]d@abd -1@a[b-d]e@abd -0@a[b-d]e@ace -0@a[b-d]@aac -0@a[-b]@a- -0@a[b-]@a- -1@a[b-a]@- -2@a[]b@- -2@a[@- -0@a]@a] -0@a[]]b@a]b -0@a[^bc]d@aed -1@a[^bc]d@abd -0@a[^-b]c@adc -1@a[^-b]c@a-c -1@a[^]b]c@a]c -0@a[^]b]c@adc -0@ab|cd@abc -0@ab|cd@abcd -0@()ef@def -0@()*@- -1@*a@- -0@^*@- -0@$*@- -1@(*)b@- -1@$b@b -2@a\@- -0@a\(b@a(b -0@a\(*b@ab -0@a\(*b@a((b -1@a\x@a\x -2@abc)@- -2@(abc@- -0@((a))@abc -0@(a)b(c)@abc -0@a+b+c@aabbabc -0@a**@- -0@a*?@- -0@(a*)*@- -0@(a*)+@- -0@(a|)*@- -0@(a*|b)*@- -0@(a+|b)*@ab -0@(a+|b)+@ab -0@(a+|b)?@ab -0@[^ab]*@cde -0@(^)*@- -0@(ab|)*@- -2@)(@- -1@abc@ -1@abc@ -0@a*@ -0@([abc])*d@abbbcd -0@([abc])*bcd@abcd -0@a|b|c|d|e@e -0@(a|b|c|d|e)f@ef -0@((a*|b))*@- -0@abcd*efg@abcdefg -0@ab*@xabyabbbz -0@ab*@xayabbbz -0@(ab|cd)e@abcde -0@[abhgefdc]ij@hij -1@^(ab|cd)e@abcde -0@(abc|)ef@abcdef -0@(a|b)c*d@abcd -0@(ab|ab*)bc@abc -0@a([bc]*)c*@abc -0@a([bc]*)(c*d)@abcd -0@a([bc]+)(c*d)@abcd -0@a([bc]*)(c+d)@abcd -0@a[bcd]*dcdcde@adcdcde -1@a[bcd]+dcdcde@adcdcde -0@(ab|a)b*c@abc -0@((a)(b)c)(d)@abcd -0@[A-Za-z_][A-Za-z0-9_]*@alpha -0@^a(bc+|b[eh])g|.h$@abh -0@(bc+d$|ef*g.|h?i(j|k))@effgz -0@(bc+d$|ef*g.|h?i(j|k))@ij -1@(bc+d$|ef*g.|h?i(j|k))@effg -1@(bc+d$|ef*g.|h?i(j|k))@bcdd -0@(bc+d$|ef*g.|h?i(j|k))@reffgz -1@((((((((((a))))))))))@- -0@(((((((((a)))))))))@a -1@multiple words of text@uh-uh -0@multiple words@multiple words, yeah -0@(.*)c(.*)@abcde -1@\((.*),@(.*)\) -1@[k]@ab -0@abcd@abcd -0@a(bc)d@abcd -0@a[-]?c@ac -0@(....).*\1@beriberi Index: gnu/usr.bin/grep/tests/spencer2.sh =================================================================== --- gnu/usr.bin/grep/tests/spencer2.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Regression test for GNU grep. - -: ${srcdir=.} - -failures=0 - -# . . . and the following by Henry Spencer. - -${AWK-awk} -f $srcdir/scriptgen.awk $srcdir/spencer2.tests > tmp2.script - -sh tmp2.script && exit $failures -exit 1 Index: gnu/usr.bin/grep/tests/spencer2.tests =================================================================== --- gnu/usr.bin/grep/tests/spencer2.tests +++ /dev/null @@ -1,317 +0,0 @@ -0@a@a -0@abc@abc -0@abc|de@abc -0@a|b|c@abc -0@a(b)c@abc -1@a\(b\)c@abc -2@a(@EPAREN -2@a(@a( -0@a\(@a( -1@a\(@EPAREN -1@a\(b@EPAREN -2@a(b@EPAREN -2@a(b@a(b -2@a)@a) -2@)@) -2@a)@a) -1@a\)@EPAREN -1@\)@EPAREN -0@a()b@ab -1@a\(\)b@ab -0@^abc$@abc -1@a^b@a^b -1@a^b@a^b -1@a$b@a$b -1@a$b@a$b -0@^@abc -0@$@abc -1@^$@"" -1@$^@"" -1@\($\)\(^\)@"" -0@^^@"" -0@$$@"" -1@b$@abNc -1@b$@abNc -1@^b$@aNbNc -1@^b$@aNbNc -1@^$@aNNb -1@^$@abc -1@^$@abcN -1@$^@aNNb -1@\($\)\(^\)@aNNb -0@^^@aNNb -0@$$@aNNb -0@^a@a -0@a$@a -0@^a@aNb -1@^b@aNb -0@a$@bNa -1@b$@bNa -0@a*(^b$)c*@b -1@a*\(^b$\)c*@b -0@|@EMPTY -0@|@| -0@*@BADRPT -0@*@* -0@+@BADRPT -0@?@BADRPT -1@""@EMPTY -0@()@abc -1@\(\)@abc -0@a||b@EMPTY -0@|ab@EMPTY -0@ab|@EMPTY -1@(|a)b@EMPTY -1@(a|)b@EMPTY -1@(*a)@BADRPT -1@(+a)@BADRPT -1@(?a)@BADRPT -1@({1}a)@BADRPT -1@\(\{1\}a\)@BADRPT -1@(a|*b)@BADRPT -1@(a|+b)@BADRPT -1@(a|?b)@BADRPT -1@(a|{1}b)@BADRPT -0@^*@BADRPT -0@^*@* -0@^+@BADRPT -0@^?@BADRPT -0@^{1}@BADRPT -1@^\{1\}@BADRPT -0@a.c@abc -0@a[bc]d@abd -0@a\*c@a*c -1@ac@abc -1@a\bc@ac -1@\{@BADRPT -0@a\[b@a[b -2@a[b@EBRACK -0@a$@a -1@a$@a$ -1@a\$@a -0@a\$@a$ -1@a\$@a -1@a\$@a\$ -2@a\(b\)\2c@ESUBREG -2@a\(b\1\)c@ESUBREG -2@a\(b*\)c\1d@abbcbd -2@a\(b*\)c\1d@abbcbbbd -2@^\(.\)\1@abc -2@a\(\([bc]\)\2\)*d@abbccd -2@a\(\([bc]\)\2\)*d@abbcbd -2@a\(\(b\)*\2\)*d@abbbd -2@\(a\)\1bcd@aabcd -2@\(a\)\1bc*d@aabcd -2@\(a\)\1bc*d@aabd -2@\(a\)\1bc*d@aabcccd -2@\(a\)\1bc*[ce]d@aabcccd -2@^\(a\)\1b\(c\)*cd$@aabcccd -0@ab*c@abc -0@ab+c@abc -0@ab?c@abc -1@a\(*\)b@a*b -1@a\(**\)b@ab -1@a\(***\)b@BADRPT -0@*a@*a -0@**a@a -1@***a@BADRPT -2@{@{ -2@{abc@{abc -2@{1@BADRPT -0@{1}@BADRPT -2@a{b@a{b -0@a{1}b@ab -1@a\{1\}b@ab -0@a{1,}b@ab -1@a\{1,\}b@ab -0@a{1,2}b@aab -1@a\{1,2\}b@aab -2@a{1@EBRACE -1@a\{1@EBRACE -2@a{1a@EBRACE -1@a\{1a@EBRACE -2@a{1a}@BADBR -1@a\{1a\}@BADBR -0@a{,2}@a{,2} -1@a\{,2\}@BADBR -0@a{,}@a{,} -1@a\{,\}@BADBR -2@a{1,x}@BADBR -1@a\{1,x\}@BADBR -2@a{1,x@EBRACE -1@a\{1,x@EBRACE -1@a{300}@BADBR -1@a\{300\}@BADBR -1@a{1,0}@BADBR -1@a\{1,0\}@BADBR -0@ab{0,0}c@abcac -1@ab\{0,0\}c@abcac -0@ab{0,1}c@abcac -1@ab\{0,1\}c@abcac -0@ab{0,3}c@abbcac -1@ab\{0,3\}c@abbcac -0@ab{1,1}c@acabc -1@ab\{1,1\}c@acabc -0@ab{1,3}c@acabc -1@ab\{1,3\}c@acabc -0@ab{2,2}c@abcabbc -1@ab\{2,2\}c@abcabbc -0@ab{2,4}c@abcabbc -1@ab\{2,4\}c@abcabbc -0@a**@BADRPT -1@a++@BADRPT -0@a??@BADRPT -0@a*+@BADRPT -0@a*?@BADRPT -0@a+*@BADRPT -0@a+?@BADRPT -0@a?*@BADRPT -0@a?+@BADRPT -1@a{1}{1}@BADRPT -0@a*{1}@BADRPT -1@a+{1}@BADRPT -0@a?{1}@BADRPT -0@a{1}*@BADRPT -1@a{1}+@BADRPT -0@a{1}?@BADRPT -2@a*{b}@a{b} -1@a\{1\}\{1\}@BADRPT -1@a*\{1\}@BADRPT -1@a\{1\}*@BADRPT -0@a[b]c@abc -0@a[ab]c@abc -0@a[^ab]c@adc -0@a[]b]c@a]c -0@a[[b]c@a[c -0@a[-b]c@a-c -0@a[^]b]c@adc -0@a[^-b]c@adc -0@a[b-]c@a-c -2@a[b@EBRACK -2@a[]@EBRACK -0@a[1-3]c@a2c -1@a[3-1]c@ERANGE -1@a[1-3-5]c@ERANGE -1@a[[.-.]--]c@a-c -2@a[1-@ERANGE -2@a[[.@EBRACK -2@a[[.x@EBRACK -2@a[[.x.@EBRACK -1@a[[.x.]@EBRACK -1@a[[.x.]]@ax -1@a[[.x,.]]@ECOLLATE -1@a[[.one.]]b@a1b -1@a[[.notdef.]]b@ECOLLATE -1@a[[.].]]b@a]b -0@a[[:alpha:]]c@abc -2@a[[:notdef:]]c@ECTYPE -2@a[[:@EBRACK -2@a[[:alpha@EBRACK -2@a[[:alpha:]@EBRACK -2@a[[:alpha,:]@ECTYPE -2@a[[:]:]]b@ECTYPE -2@a[[:-:]]b@ECTYPE -2@a[[:alph:]]@ECTYPE -2@a[[:alphabet:]]@ECTYPE -1@[[:blank:]]+@aSSTb -1@[[:cntrl:]]+@aNTb -0@[[:digit:]]+@a019b -0@[[:graph:]]+@Sa%bS -0@[[:lower:]]+@AabC -0@[[:print:]]+@NaSbN -0@[[:punct:]]+@S%-&T -1@[[:space:]]+@aSNTb -0@[[:upper:]]+@aBCd -0@[[:xdigit:]]+@p0f3Cq -1@a[[=b=]]c@abc -2@a[[=@EBRACK -2@a[[=b@EBRACK -2@a[[=b=@EBRACK -1@a[[=b=]@EBRACK -1@a[[=b,=]]@ECOLLATE -1@a[[=one=]]b@a1b -0@a(((b)))c@abc -0@a(b|(c))d@abd -0@a(b*|c)d@abbd -0@a[ab]{20}@aaaaabaaaabaaaabaaaab -0@a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab]@aaaaabaaaabaaaabaaaab -0@a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night)@aaaaabaaaabaaaabaaaabweeknights -0@12345678901234567890123456789@a12345678901234567890123456789b -0@123456789012345678901234567890@a123456789012345678901234567890b -0@1234567890123456789012345678901@a1234567890123456789012345678901b -0@12345678901234567890123456789012@a12345678901234567890123456789012b -0@123456789012345678901234567890123@a123456789012345678901234567890123b -0@1234567890123456789012345678901234567890123456789012345678901234567890@a1234567890123456789012345678901234567890123456789012345678901234567890b -0@[ab][cd][ef][gh][ij][kl][mn]@xacegikmoq -0@[ab][cd][ef][gh][ij][kl][mn][op]@xacegikmoq -0@[ab][cd][ef][gh][ij][kl][mn][op][qr]@xacegikmoqy -0@[ab][cd][ef][gh][ij][kl][mn][op][q]@xacegikmoqy -0@abc@xabcy -2@a\(b\)?c\1d@acd -1@aBc@Abc -1@a[Bc]*d@abBCcd -1@0[[:upper:]]1@0a1 -1@0[[:lower:]]1@0A1 -1@a[^b]c@abc -0@a[^b]c@aBc -0@a[^b]c@adc -0@[a]b[c]@abc -0@[a]b[a]@aba -0@[abc]b[abc]@abc -0@[abc]b[abd]@abd -0@a(b?c)+d@accd -0@(wee|week)(knights|night)@weeknights -0@(we|wee|week|frob)(knights|night|day)@weeknights -0@a[bc]d@xyzaaabcaababdacd -0@a[ab]c@aaabc -0@abc@abc -0@a*@b -0@/\*.*\*/@/*x*/ -0@/\*.*\*/@/*x*/y/*z*/ -0@/\*([^*]|\*[^/])*\*/@/*x*/ -0@/\*([^*]|\*[^/])*\*/@/*x*/y/*z*/ -0@/\*([^*]|\*[^/])*\*/@/*x**/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x*/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x**/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x****/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x**x*/y/*z*/ -0@/\*([^*]|\*+[^*/])*\*+/@/*x***x/y/*z*/ -0@[abc]@a(b)c -0@[abc]@a(d)c -0@[abc]@a(bc)d -0@[abc]@a(dc)d -0@.@a()c -0@b.*c@b(bc)c -0@b.*@b(bc)c -0@.*c@b(bc)c -0@abc@abc -0@abc@xabcy -1@abc@xyz -0@a*b@aba*b -0@a*b@ab -1@""@EMPTY -1@aZb@a -1@aZb@a -0@aZb@(aZb) -0@aZ*b@(ab) -0@a.b@(aZb) -0@a.*@(aZb)c -2@[[:<:]]a@a -2@[[:<:]]a@ba -2@[[:<:]]a@-a -2@a[[:>:]]@a -2@a[[:>:]]@ab -2@a[[:>:]]@a- -2@[[:<:]]a.c[[:>:]]@axcd-dayc-dazce-abc -2@[[:<:]]a.c[[:>:]]@axcd-dayc-dazce-abc-q -2@[[:<:]]a.c[[:>:]]@axc-dayc-dazce-abc -2@[[:<:]]b.c[[:>:]]@a_bxc-byc_d-bzc-q -2@[[:<:]].x..[[:>:]]@y_xa_-_xb_y-_xc_-axdc -2@[[:<:]]a_b[[:>:]]@x_a_b -0@(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A])@A1 -0@abcdefghijklmnop@abcdefghijklmnop -0@abcdefghijklmnopqrstuv@abcdefghijklmnopqrstuv -0@CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a@CC11 -0@a?b@ab -1@-\{0,1\}[0-9]*$@-5 Index: gnu/usr.bin/grep/tests/status.sh =================================================================== --- gnu/usr.bin/grep/tests/status.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# Test for status code for GNU grep. -# status code -# 0 match found -# 1 no match -# 2 file not found - -: ${srcdir=.} - -failures=0 - -# should return 0 found a match -echo "abcd" | ${GREP} -E -e 'abc' > /dev/null 2>&1 -if test $? -ne 0 ; then - echo "Status: Wrong status code, test \#1 failed" - failures=1 -fi - -# should return 1 found no match -echo "abcd" | ${GREP} -E -e 'zbc' > /dev/null 2>&1 -if test $? -ne 1 ; then - echo "Status: Wrong status code, test \#2 failed" - failures=1 -fi - -# the filename MMMMMMMM.MMM should not exist hopefully -if test -r MMMMMMMM.MMM; then - echo "Please remove MMMMMMMM.MMM to run check" -else - # should return 2 file not found - ${GREP} -E -e 'abc' MMMMMMMM.MMM > /dev/null 2>&1 - if test $? -ne 2 ; then - echo "Status: Wrong status code, test \#3 failed" - failures=1 - fi - - # should return 2 file not found - ${GREP} -E -s -e 'abc' MMMMMMMM.MMM > /dev/null 2>&1 - if test $? -ne 2 ; then - echo "Status: Wrong status code, test \#4 failed" - failures=1 - fi - - # should return 0 found a match - echo "abcd" | ${GREP} -E -q -s 'abc' MMMMMMMM.MMM - > /dev/null 2>&1 - if test $? -ne 0 ; then - echo "Status: Wrong status code, test \#5 failed" - failures=1 - fi -fi - -exit $failures Index: gnu/usr.bin/grep/tests/tests =================================================================== --- gnu/usr.bin/grep/tests/tests +++ /dev/null @@ -1,475 +0,0 @@ -# regular expression test set -# Lines are at least three fields, separated by one or more tabs. "" stands -# for an empty field. First field is an RE. Second field is flags. If -# C flag given, regcomp() is expected to fail, and the third field is the -# error name (minus the leading REG_). -# -# Otherwise it is expected to succeed, and the third field is the string to -# try matching it against. If there is no fourth field, the match is -# expected to fail. If there is a fourth field, it is the substring that -# the RE is expected to match. If there is a fifth field, it is a comma- -# separated list of what the subexpressions should match, with - indicating -# no match for that one. In both the fourth and fifth fields, a (sub)field -# starting with @ indicates that the (sub)expression is expected to match -# a null string followed by the stuff after the @; this provides a way to -# test where null strings match. The character `N' in REs and strings -# is newline, `S' is space, `T' is tab, `Z' is NUL. -# -# The full list of flags: -# - placeholder, does nothing -# b RE is a BRE, not an ERE -# & try it as both an ERE and a BRE -# C regcomp() error expected, third field is error name -# i REG_ICASE -# m ("mundane") REG_NOSPEC -# s REG_NOSUB (not really testable) -# n REG_NEWLINE -# ^ REG_NOTBOL -# $ REG_NOTEOL -# # REG_STARTEND (see below) -# p REG_PEND -# -# For REG_STARTEND, the start/end offsets are those of the substring -# enclosed in (). - -# basics -a & a a -abc & abc abc -abc|de - abc abc -a|b|c - abc a - -# parentheses and perversions thereof -a(b)c - abc abc -a\(b\)c b abc abc -a( C EPAREN -a( b a( a( -a\( - a( a( -a\( bC EPAREN -a\(b bC EPAREN -a(b C EPAREN -a(b b a(b a(b -# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) -a) - a) a) -) - ) ) -# end gagging (in a just world, those *should* give EPAREN) -a) b a) a) -a\) bC EPAREN -\) bC EPAREN -a()b - ab ab -a\(\)b b ab ab - -# anchoring and REG_NEWLINE -^abc$ & abc abc -a^b - a^b -a^b b a^b a^b -a$b - a$b -a$b b a$b a$b -^ & abc @abc -$ & abc @ -^$ & "" @ -$^ - "" @ -\($\)\(^\) b "" @ -# stop retching, those are legitimate (although disgusting) -^^ - "" @ -$$ - "" @ -##b$ & abNc -##b$ &n abNc b -##^b$ & aNbNc -##^b$ &n aNbNc b -##^$ &n aNNb @Nb -^$ n abc -##^$ n abcN @ -##$^ n aNNb @Nb -##\($\)\(^\) bn aNNb @Nb -##^^ n^ aNNb @Nb -##$$ n aNNb @NN -^a ^ a -a$ $ a -##^a ^n aNb -##^b ^n aNb b -##a$ $n bNa -##b$ $n bNa b -a*(^b$)c* - b b -a*\(^b$\)c* b b b - -# certain syntax errors and non-errors -| C EMPTY -| b | | -* C BADRPT -* b * * -+ C BADRPT -? C BADRPT -"" &C EMPTY -() - abc @abc -\(\) b abc @abc -a||b C EMPTY -|ab C EMPTY -ab| C EMPTY -(|a)b C EMPTY -(a|)b C EMPTY -(*a) C BADRPT -(+a) C BADRPT -(?a) C BADRPT -({1}a) C BADRPT -\(\{1\}a\) bC BADRPT -(a|*b) C BADRPT -(a|+b) C BADRPT -(a|?b) C BADRPT -(a|{1}b) C BADRPT -^* C BADRPT -^* b * * -^+ C BADRPT -^? C BADRPT -^{1} C BADRPT -^\{1\} bC BADRPT - -# metacharacters, backslashes -a.c & abc abc -a[bc]d & abd abd -a\*c & a*c a*c -a\\b & a\b a\b -a\\\*b & a\*b a\*b -a\bc & abc abc -a\ &C EESCAPE -a\\bc & a\bc a\bc -\{ bC BADRPT -a\[b & a[b a[b -a[b &C EBRACK -# trailing $ is a peculiar special case for the BRE code -a$ & a a -a$ & a$ -a\$ & a -a\$ & a$ a$ -a\\$ & a -a\\$ & a$ -a\\$ & a\$ -a\\$ & a\ a\ - -# back references, ugh -##a\(b\)\2c bC ESUBREG -##a\(b\1\)c bC ESUBREG -a\(b*\)c\1d b abbcbbd abbcbbd bb -a\(b*\)c\1d b abbcbd -a\(b*\)c\1d b abbcbbbd -^\(.\)\1 b abc -a\([bc]\)\1d b abcdabbd abbd b -a\(\([bc]\)\2\)*d b abbccd abbccd -a\(\([bc]\)\2\)*d b abbcbd -# actually, this next one probably ought to fail, but the spec is unclear -a\(\(b\)*\2\)*d b abbbd abbbd -# here is a case that no NFA implementation does right -\(ab*\)[ab]*\1 b ababaaa ababaaa a -# check out normal matching in the presence of back refs -\(a\)\1bcd b aabcd aabcd -\(a\)\1bc*d b aabcd aabcd -\(a\)\1bc*d b aabd aabd -\(a\)\1bc*d b aabcccd aabcccd -\(a\)\1bc*[ce]d b aabcccd aabcccd -^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd - -# ordinary repetitions -ab*c & abc abc -ab+c - abc abc -ab?c - abc abc -a\(*\)b b a*b a*b -a\(**\)b b ab ab -a\(***\)b bC BADRPT -*a b *a *a -**a b a a -***a bC BADRPT - -# the dreaded bounded repetitions -{ & { { -{abc & {abc {abc -{1 C BADRPT -{1} C BADRPT -a{b & a{b a{b -a{1}b - ab ab -a\{1\}b b ab ab -a{1,}b - ab ab -a\{1,\}b b ab ab -a{1,2}b - aab aab -a\{1,2\}b b aab aab -a{1 C EBRACE -a\{1 bC EBRACE -a{1a C EBRACE -a\{1a bC EBRACE -a{1a} C BADBR -a\{1a\} bC BADBR -a{,2} - a{,2} a{,2} -a\{,2\} bC BADBR -a{,} - a{,} a{,} -a\{,\} bC BADBR -a{1,x} C BADBR -a\{1,x\} bC BADBR -a{1,x C EBRACE -a\{1,x bC EBRACE -a{300} C BADBR -a\{300\} bC BADBR -a{1,0} C BADBR -a\{1,0\} bC BADBR -ab{0,0}c - abcac ac -ab\{0,0\}c b abcac ac -ab{0,1}c - abcac abc -ab\{0,1\}c b abcac abc -ab{0,3}c - abbcac abbc -ab\{0,3\}c b abbcac abbc -ab{1,1}c - acabc abc -ab\{1,1\}c b acabc abc -ab{1,3}c - acabc abc -ab\{1,3\}c b acabc abc -ab{2,2}c - abcabbc abbc -ab\{2,2\}c b abcabbc abbc -ab{2,4}c - abcabbc abbc -ab\{2,4\}c b abcabbc abbc -((a{1,10}){1,10}){1,10} - a a a,a - -# multiple repetitions -a** &C BADRPT -a++ C BADRPT -a?? C BADRPT -a*+ C BADRPT -a*? C BADRPT -a+* C BADRPT -a+? C BADRPT -a?* C BADRPT -a?+ C BADRPT -a{1}{1} C BADRPT -a*{1} C BADRPT -a+{1} C BADRPT -a?{1} C BADRPT -a{1}* C BADRPT -a{1}+ C BADRPT -a{1}? C BADRPT -a*{b} - a{b} a{b} -a\{1\}\{1\} bC BADRPT -a*\{1\} bC BADRPT -a\{1\}* bC BADRPT - -# brackets, and numerous perversions thereof -a[b]c & abc abc -a[ab]c & abc abc -a[^ab]c & adc adc -a[]b]c & a]c a]c -a[[b]c & a[c a[c -a[-b]c & a-c a-c -a[^]b]c & adc adc -a[^-b]c & adc adc -a[b-]c & a-c a-c -a[b &C EBRACK -a[] &C EBRACK -a[1-3]c & a2c a2c -a[3-1]c &C ERANGE -a[1-3-5]c &C ERANGE -a[[.-.]--]c & a-c a-c -a[1- &C ERANGE -a[[. &C EBRACK -a[[.x &C EBRACK -a[[.x. &C EBRACK -a[[.x.] &C EBRACK -a[[.x.]] & ax ax -a[[.x,.]] &C ECOLLATE -a[[.one.]]b & a1b a1b -a[[.notdef.]]b &C ECOLLATE -a[[.].]]b & a]b a]b -a[[:alpha:]]c & abc abc -a[[:notdef:]]c &C ECTYPE -a[[: &C EBRACK -a[[:alpha &C EBRACK -a[[:alpha:] &C EBRACK -a[[:alpha,:] &C ECTYPE -a[[:]:]]b &C ECTYPE -a[[:-:]]b &C ECTYPE -a[[:alph:]] &C ECTYPE -a[[:alphabet:]] &C ECTYPE -##[[:alnum:]]+ - -%@a0X- a0X -##[[:alpha:]]+ - -%@aX0- aX -[[:blank:]]+ - aSSTb SST -##[[:cntrl:]]+ - aNTb NT -[[:digit:]]+ - a019b 019 -##[[:graph:]]+ - Sa%bS a%b -[[:lower:]]+ - AabC ab -##[[:print:]]+ - NaSbN aSb -##[[:punct:]]+ - S%-&T %-& -[[:space:]]+ - aSNTb SNT -[[:upper:]]+ - aBCd BC -[[:xdigit:]]+ - p0f3Cq 0f3C -a[[=b=]]c & abc abc -a[[= &C EBRACK -a[[=b &C EBRACK -a[[=b= &C EBRACK -a[[=b=] &C EBRACK -a[[=b,=]] &C ECOLLATE -a[[=one=]]b & a1b a1b - -# complexities -a(((b)))c - abc abc -a(b|(c))d - abd abd -a(b*|c)d - abbd abbd -# just gotta have one DFA-buster, of course -a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab -# and an inline expansion in case somebody gets tricky -a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab -# and in case somebody just slips in an NFA... -a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights -# fish for anomalies as the number of states passes 32 -12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 -123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 -1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 -12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 -123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 -# and one really big one, beyond any plausible word width -1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 -# fish for problems as brackets go past 8 -[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm -[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo -[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq -[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq - -# subtleties of matching -abc & xabcy abc -a\(b\)?c\1d b acd -aBc i Abc Abc -a[Bc]*d i abBCcd abBCcd -0[[:upper:]]1 &i 0a1 0a1 -0[[:lower:]]1 &i 0A1 0A1 -a[^b]c &i abc -a[^b]c &i aBc -a[^b]c &i adc adc -[a]b[c] - abc abc -[a]b[a] - aba aba -[abc]b[abc] - abc abc -[abc]b[abd] - abd abd -a(b?c)+d - accd accd -(wee|week)(knights|night) - weeknights weeknights -(we|wee|week|frob)(knights|night|day) - weeknights weeknights -a[bc]d - xyzaaabcaababdacd abd -a[ab]c - aaabc abc -abc s abc abc -a* & b @b - -# Let's have some fun -- try to match a C comment. -# first the obvious, which looks okay at first glance... -/\*.*\*/ - /*x*/ /*x*/ -# but... -/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/ -# okay, we must not match */ inside; try to do that... -/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/ -/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/ -# but... -/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/ -# and a still fancier version, which does it right (I think)... -/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/ -/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/ -/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/ -/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/ -/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/ -/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/ - -# subexpressions -a(b)(c)d - abcd abcd b,c -a(((b)))c - abc abc b,b,b -a(b|(c))d - abd abd b,- -a(b*|c|e)d - abbd abbd bb -a(b*|c|e)d - acd acd c -a(b*|c|e)d - ad ad @d -a(b?)c - abc abc b -a(b?)c - ac ac @c -a(b+)c - abc abc b -a(b+)c - abbbc abbbc bbb -a(b*)c - ac ac @c -(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de -# the regression tester only asks for 9 subexpressions -a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j -a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k -a([bc]?)c - abc abc b -a([bc]?)c - ac ac @c -a([bc]+)c - abc abc b -a([bc]+)c - abcc abcc bc -a([bc]+)bc - abcbc abcbc bc -a(bb+|b)b - abb abb b -a(bbb+|bb+|b)b - abb abb b -a(bbb+|bb+|b)b - abbb abbb bb -a(bbb+|bb+|b)bb - abbb abbb b -(.*).* - abcdef abcdef abcdef -##(a*)* - bc @b @b - -# do we get the right subexpression when it is used more than once? -a(b|c)*d - ad ad - -a(b|c)*d - abcd abcd c -a(b|c)+d - abd abd b -a(b|c)+d - abcd abcd c -a(b|c?)+d - ad ad @d -a(b|c?)+d - abcd abcd @d -a(b|c){0,0}d - ad ad - -a(b|c){0,1}d - ad ad - -a(b|c){0,1}d - abd abd b -a(b|c){0,2}d - ad ad - -a(b|c){0,2}d - abcd abcd c -a(b|c){0,}d - ad ad - -a(b|c){0,}d - abcd abcd c -a(b|c){1,1}d - abd abd b -a(b|c){1,1}d - acd acd c -a(b|c){1,2}d - abd abd b -a(b|c){1,2}d - abcd abcd c -a(b|c){1,}d - abd abd b -a(b|c){1,}d - abcd abcd c -a(b|c){2,2}d - acbd acbd b -a(b|c){2,2}d - abcd abcd c -a(b|c){2,4}d - abcd abcd c -a(b|c){2,4}d - abcbd abcbd b -a(b|c){2,4}d - abcbcd abcbcd c -a(b|c){2,}d - abcd abcd c -a(b|c){2,}d - abcbd abcbd b -##a(b+|((c)*))+d - abd abd @d,@d,- -##a(b+|((c)*))+d - abcd abcd @d,@d,- - -# check out the STARTEND option -[abc] &# a(b)c b -[abc] &# a(d)c -[abc] &# a(bc)d b -[abc] &# a(dc)d c -. &# a()c -b.*c &# b(bc)c bc -b.* &# b(bc)c bc -.*c &# b(bc)c bc - -# plain strings, with the NOSPEC flag -abc m abc abc -abc m xabcy abc -abc m xyz -a*b m aba*b a*b -a*b m ab -"" mC EMPTY - -# cases involving NULs -aZb & a a -aZb &p a -#aZb &p# (aZb) aZb -aZ*b &p# (ab) ab -#a.b &# (aZb) aZb -#a.* &# (aZb)c aZb - -# word boundaries (ick) -[[:<:]]a & a a -[[:<:]]a & ba -[[:<:]]a & -a a -a[[:>:]] & a a -a[[:>:]] & ab -a[[:>:]] & a- a -[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc -[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc -[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc -[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc -[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_ -[[:<:]]a_b[[:>:]] & x_a_b - -# past problems, and suspected problems -(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 -abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop -abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv -(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 -CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 -Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz -a?b - ab ab --\{0,1\}[0-9]*$ b -5 -5 Index: gnu/usr.bin/grep/tests/warning.sh =================================================================== --- gnu/usr.bin/grep/tests/warning.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# -# Tell them not to be alarmed. - -: ${srcdir=.} - -failures=0 - -# -cat <<\EOF - -Please, do not be alarmed if some of the tests failed. -Report them to , -with the line number, the name of the file, -and grep version number 'grep --version'. -Make sure you have the word grep in the subject. -Thank You. - -EOF Index: gnu/usr.bin/grep/xalloc.h =================================================================== --- gnu/usr.bin/grep/xalloc.h +++ /dev/null @@ -1,87 +0,0 @@ -/* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990-1998, 1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef XALLOC_H_ -# define XALLOC_H_ - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -# ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -# endif - -# ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -# endif - -/* Exit value when the requested amount of memory is not available. - It is initialized to EXIT_FAILURE, but the caller may set it to - some other value. */ -extern int xalloc_exit_failure; - -/* If this pointer is non-zero, run the specified function upon each - allocation failure. It is initialized to zero. */ -extern void (*xalloc_fail_func) PARAMS ((void)); - -/* If XALLOC_FAIL_FUNC is undefined or a function that returns, this - message is output. It is translated via gettext. - Its value is "memory exhausted". */ -extern char const xalloc_msg_memory_exhausted[]; - -/* This function is always triggered when memory is exhausted. It is - in charge of honoring the three previous items. This is the - function to call when one wants the program to die because of a - memory allocation failure. */ -extern void xalloc_die PARAMS ((void)) ATTRIBUTE_NORETURN; - -void *xmalloc PARAMS ((size_t n)); -void *xcalloc PARAMS ((size_t n, size_t s)); -void *xrealloc PARAMS ((void *p, size_t n)); -char *xstrdup PARAMS ((const char *str)); - -# define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items))) -# define XCALLOC(Type, N_items) ((Type *) xcalloc (sizeof (Type), (N_items))) -# define XREALLOC(Ptr, Type, N_items) \ - ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items))) - -/* Declare and alloc memory for VAR of type TYPE. */ -# define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) - -/* Free VAR only if non NULL. */ -# define XFREE(Var) \ - do { \ - if (Var) \ - free (Var); \ - } while (0) - -/* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ -# define CCLONE(Src, Num) \ - (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num))) - -/* Return a malloc'ed copy of SRC. */ -# define CLONE(Src) CCLONE (Src, 1) - - -#endif /* !XALLOC_H_ */ Index: gnu/usr.bin/grep/xmalloc.c =================================================================== --- gnu/usr.bin/grep/xmalloc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* xmalloc.c -- malloc with out of memory checking - Copyright (C) 1990-1999, 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include - -#if STDC_HEADERS -# include -#else -void *calloc (); -void *malloc (); -void *realloc (); -void free (); -#endif - -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define textdomain(Domain) -# define _(Text) Text -#endif -#define N_(Text) Text - -#include "error.h" -#include "xalloc.h" - -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -#ifndef HAVE_DONE_WORKING_MALLOC_CHECK -"you must run the autoconf test for a properly working malloc -- see malloc.m4" -#endif - -#ifndef HAVE_DONE_WORKING_REALLOC_CHECK -"you must run the autoconf test for a properly working realloc --see realloc.m4" -#endif - -/* Exit value when the requested amount of memory is not available. - The caller may set it to some other value. */ -int xalloc_exit_failure = EXIT_FAILURE; - -/* If non NULL, call this function when memory is exhausted. */ -void (*xalloc_fail_func) PARAMS ((void)) = 0; - -/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message - before exiting when memory is exhausted. Goes through gettext. */ -char const xalloc_msg_memory_exhausted[] = N_("memory exhausted"); - -void -xalloc_die (void) -{ - if (xalloc_fail_func) - (*xalloc_fail_func) (); - error (xalloc_exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted)); - /* The `noreturn' cannot be given to error, since it may return if - its first argument is 0. To help compilers understand the - xalloc_die does terminate, call exit. */ - exit (EXIT_FAILURE); -} - -/* Allocate N bytes of memory dynamically, with error checking. */ - -void * -xmalloc (size_t n) -{ - void *p; - - p = malloc (n); - if (p == 0) - xalloc_die (); - return p; -} - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. */ - -void * -xrealloc (void *p, size_t n) -{ - p = realloc (p, n); - if (p == 0) - xalloc_die (); - return p; -} - -/* Allocate memory for N elements of S bytes, with error checking. */ - -void * -xcalloc (size_t n, size_t s) -{ - void *p; - - p = calloc (n, s); - if (p == 0) - xalloc_die (); - return p; -} Index: gnu/usr.bin/grep/xstrtol.h =================================================================== --- gnu/usr.bin/grep/xstrtol.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef XSTRTOL_H_ -# define XSTRTOL_H_ 1 - -# if HAVE_INTTYPES_H -# include /* for uintmax_t */ -# endif - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -# ifndef _STRTOL_ERROR -enum strtol_error - { - LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW - }; -typedef enum strtol_error strtol_error; -# endif - -# define _DECLARE_XSTRTOL(name, type) \ - strtol_error \ - name PARAMS ((const char *s, char **ptr, int base, \ - type *val, const char *valid_suffixes)); -_DECLARE_XSTRTOL (xstrtol, long int) -_DECLARE_XSTRTOL (xstrtoul, unsigned long int) -_DECLARE_XSTRTOL (xstrtoumax, uintmax_t) - -# define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \ - do \ - { \ - switch ((Err)) \ - { \ - case LONGINT_OK: \ - abort (); \ - \ - case LONGINT_INVALID: \ - error ((Exit_code), 0, "invalid %s `%s'", \ - (Argument_type_string), (Str)); \ - break; \ - \ - case LONGINT_INVALID_SUFFIX_CHAR: \ - error ((Exit_code), 0, "invalid character following %s `%s'", \ - (Argument_type_string), (Str)); \ - break; \ - \ - case LONGINT_OVERFLOW: \ - error ((Exit_code), 0, "%s `%s' too large", \ - (Argument_type_string), (Str)); \ - break; \ - } \ - } \ - while (0) - -# define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \ - _STRTOL_ERROR (2, Str, Argument_type_string, Err) - -# define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \ - _STRTOL_ERROR (0, Str, Argument_type_string, Err) - -#endif /* not XSTRTOL_H_ */ Index: gnu/usr.bin/grep/xstrtol.c =================================================================== --- gnu/usr.bin/grep/xstrtol.c +++ /dev/null @@ -1,282 +0,0 @@ -/* A more useful interface to strtol. - Copyright (C) 1995, 1996, 1998-2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Jim Meyering. */ - -#if HAVE_CONFIG_H -# include -#endif - -#ifndef __strtol -# define __strtol strtol -# define __strtol_t long int -# define __xstrtol xstrtol -#endif - -/* Some pre-ANSI implementations (e.g. SunOS 4) - need stderr defined if assertion checking is enabled. */ -#include - -#if STDC_HEADERS -# include -#endif - -#if HAVE_STRING_H -# include -#else -# include -# ifndef strchr -# define strchr index -# endif -#endif - -#include -#include - -#include -#ifndef errno -extern int errno; -#endif - -#if HAVE_LIMITS_H -# include -#endif - -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif - -/* The extra casts work around common compiler bugs. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. - It is necessary at least when t == time_t. */ -#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ - ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) -#define TYPE_MAXIMUM(t) (~ (t) 0 - TYPE_MINIMUM (t)) - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) isascii(c) -#endif - -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) - -#include "xstrtol.h" - -#ifndef strtol -long int strtol (); -#endif - -#ifndef strtoul -unsigned long int strtoul (); -#endif - -#ifndef strtoumax -uintmax_t strtoumax (); -#endif - -static int -bkm_scale (__strtol_t *x, int scale_factor) -{ - __strtol_t product = *x * scale_factor; - if (*x != product / scale_factor) - return 1; - *x = product; - return 0; -} - -static int -bkm_scale_by_power (__strtol_t *x, int base, int power) -{ - while (power--) - if (bkm_scale (x, base)) - return 1; - - return 0; -} - -/* FIXME: comment. */ - -strtol_error -__xstrtol (const char *s, char **ptr, int strtol_base, - __strtol_t *val, const char *valid_suffixes) -{ - char *t_ptr; - char **p; - __strtol_t tmp; - - assert (0 <= strtol_base && strtol_base <= 36); - - p = (ptr ? ptr : &t_ptr); - - if (! TYPE_SIGNED (__strtol_t)) - { - const char *q = s; - while (ISSPACE ((unsigned char) *q)) - ++q; - if (*q == '-') - return LONGINT_INVALID; - } - - errno = 0; - tmp = __strtol (s, p, strtol_base); - if (errno != 0) - return LONGINT_OVERFLOW; - if (*p == s) - return LONGINT_INVALID; - - /* Let valid_suffixes == NULL mean `allow any suffix'. */ - /* FIXME: update all callers except the ones that allow suffixes - after the number, changing last parameter NULL to `""'. */ - if (!valid_suffixes) - { - *val = tmp; - return LONGINT_OK; - } - - if (**p != '\0') - { - int base = 1024; - int suffixes = 1; - int overflow; - - if (!strchr (valid_suffixes, **p)) - { - *val = tmp; - return LONGINT_INVALID_SUFFIX_CHAR; - } - - if (strchr (valid_suffixes, '0')) - { - /* The ``valid suffix'' '0' is a special flag meaning that - an optional second suffix is allowed, which can change - the base, e.g. "100MD" for 100 megabytes decimal. */ - - switch (p[0][1]) - { - case 'B': - suffixes++; - break; - - case 'D': - base = 1000; - suffixes++; - break; - } - } - - switch (**p) - { - case 'b': - overflow = bkm_scale (&tmp, 512); - break; - - case 'B': - overflow = bkm_scale (&tmp, 1024); - break; - - case 'c': - overflow = 0; - break; - - case 'E': /* Exa */ - overflow = bkm_scale_by_power (&tmp, base, 6); - break; - - case 'G': /* Giga */ - overflow = bkm_scale_by_power (&tmp, base, 3); - break; - - case 'k': /* kilo */ - overflow = bkm_scale_by_power (&tmp, base, 1); - break; - - case 'M': /* Mega */ - case 'm': /* 'm' is undocumented; for backward compatibility only */ - overflow = bkm_scale_by_power (&tmp, base, 2); - break; - - case 'P': /* Peta */ - overflow = bkm_scale_by_power (&tmp, base, 5); - break; - - case 'T': /* Tera */ - overflow = bkm_scale_by_power (&tmp, base, 4); - break; - - case 'w': - overflow = bkm_scale (&tmp, 2); - break; - - case 'Y': /* Yotta */ - overflow = bkm_scale_by_power (&tmp, base, 8); - break; - - case 'Z': /* Zetta */ - overflow = bkm_scale_by_power (&tmp, base, 7); - break; - - default: - *val = tmp; - return LONGINT_INVALID_SUFFIX_CHAR; - break; - } - - if (overflow) - return LONGINT_OVERFLOW; - - (*p) += suffixes; - } - - *val = tmp; - return LONGINT_OK; -} - -#ifdef TESTING_XSTRTO - -# include -# include "error.h" - -char *program_name; - -int -main (int argc, char** argv) -{ - strtol_error s_err; - int i; - - program_name = argv[0]; - for (i=1; i%lu (%s)\n", argv[i], val, p); - } - else - { - STRTOL_FATAL_ERROR (argv[i], "arg", s_err); - } - } - exit (0); -} - -#endif /* TESTING_XSTRTO */ Index: gnu/usr.bin/grep/xstrtoumax.c =================================================================== --- gnu/usr.bin/grep/xstrtoumax.c +++ /dev/null @@ -1,31 +0,0 @@ -/* xstrtoumax.c -- A more useful interface to strtoumax. - Copyright 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert. */ - -#if HAVE_CONFIG_H -# include -#endif - -#if HAVE_INTTYPES_H -# include -#endif - -#define __strtol strtoumax -#define __strtol_t uintmax_t -#define __xstrtol xstrtoumax -#include "xstrtol.c" Index: share/man/man5/src.conf.5 =================================================================== --- share/man/man5/src.conf.5 +++ share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd December 15, 2020 +.Dd December 22, 2020 .Dt SRC.CONF 5 .Os .Sh NAME @@ -222,8 +222,6 @@ .It Va WITHOUT_BSD_CPIO Set to not build the BSD licensed version of cpio based on .Xr libarchive 3 . -.It Va WITHOUT_BSD_GREP -Install GNU grep as '[ef]grep' instead of BSD grep. .It Va WITHOUT_BSNMP Set to not build or install .Xr bsnmpd 1 @@ -665,9 +663,6 @@ .It Va WITHOUT_GNU_DIFF Set to not build GNU .Xr diff3 1 . -.It Va WITH_GNU_GREP -Build and install GNU -.Xr grep 1 . .It Va WITHOUT_GOOGLETEST Set to neither build nor install .Lb libgmock , Index: share/mk/bsd.libnames.mk =================================================================== --- share/mk/bsd.libnames.mk +++ share/mk/bsd.libnames.mk @@ -67,7 +67,6 @@ LIBFORM?= ${LIBDESTDIR}${LIBDIR_BASE}/libform.a LIBG2C?= ${LIBDESTDIR}${LIBDIR_BASE}/libg2c.a LIBGEOM?= ${LIBDESTDIR}${LIBDIR_BASE}/libgeom.a -LIBGNUREGEX?= ${LIBDESTDIR}${LIBDIR_BASE}/libgnuregex.a LIBGPIO?= ${LIBDESTDIR}${LIBDIR_BASE}/libgpio.a LIBGSSAPI?= ${LIBDESTDIR}${LIBDIR_BASE}/libgssapi.a LIBGSSAPI_KRB5?= ${LIBDESTDIR}${LIBDIR_BASE}/libgssapi_krb5.a Index: share/mk/src.libnames.mk =================================================================== --- share/mk/src.libnames.mk +++ share/mk/src.libnames.mk @@ -117,7 +117,6 @@ fetch \ figpar \ geom \ - gnuregex \ gpio \ gssapi \ gssapi_krb5 \ @@ -624,7 +623,6 @@ LIBOSMVENDORDIR=${OBJTOP}/lib/ofed/libvendor LIBDIALOGDIR= ${OBJTOP}/gnu/lib/libdialog -LIBGNUREGEXDIR= ${OBJTOP}/gnu/lib/libregex LIBSSPDIR= ${OBJTOP}/lib/libssp LIBSSP_NONSHAREDDIR= ${OBJTOP}/lib/libssp_nonshared LIBASN1DIR= ${OBJTOP}/kerberos5/lib/libasn1 Index: share/mk/src.opts.mk =================================================================== --- share/mk/src.opts.mk +++ share/mk/src.opts.mk @@ -68,7 +68,6 @@ BOOTPARAMD \ BOOTPD \ BSD_CPIO \ - BSD_GREP \ BSDINSTALL \ BSNMP \ BZIP2 \ @@ -206,7 +205,6 @@ CLANG_FORMAT \ DTRACE_TESTS \ EXPERIMENTAL \ - GNU_GREP \ HESIOD \ LIBSOFT \ LOADER_FIREWIRE \ Index: tools/build/mk/OptionalObsoleteFiles.inc =================================================================== --- tools/build/mk/OptionalObsoleteFiles.inc +++ tools/build/mk/OptionalObsoleteFiles.inc @@ -2312,31 +2312,6 @@ OLD_FILES+=usr/share/man/man1/diff3.1.gz .endif -.if ${MK_GNU_GREP} == no -OLD_FILES+=usr/bin/gnugrep -OLD_FILES+=usr/share/man/man1/gnugrep.1.gz -.if ${MK_BSD_GREP} == no -OLD_FILES+=usr/bin/bzgrep -OLD_FILES+=usr/bin/bzegrep -OLD_FILES+=usr/bin/bzfgrep -OLD_FILES+=usr/bin/egrep -OLD_FILES+=usr/bin/fgrep -OLD_FILES+=usr/bin/grep -OLD_FILES+=usr/bin/zegrep -OLD_FILES+=usr/bin/zfgrep -OLD_FILES+=usr/bin/zgrep -OLD_FILES+=usr/share/man/man1/bzegrep.1.gz -OLD_FILES+=usr/share/man/man1/bzfgrep.1.gz -OLD_FILES+=usr/share/man/man1/bzgrep.1.gz -OLD_FILES+=usr/share/man/man1/egrep.1.gz -OLD_FILES+=usr/share/man/man1/fgrep.1.gz -OLD_FILES+=usr/share/man/man1/grep.1.gz -OLD_FILES+=usr/share/man/man1/zegrep.1.gz -OLD_FILES+=usr/share/man/man1/zfgrep.1.gz -OLD_FILES+=usr/share/man/man1/zgrep.1.gz -.endif -.endif - .if ${MK_GSSAPI} == no OLD_FILES+=usr/include/gssapi/gssapi.h OLD_DIRS+=usr/include/gssapi @@ -7440,7 +7415,6 @@ OLD_FILES+=usr/lib/libgcc_eh_p.a OLD_FILES+=usr/lib/libgcc_p.a OLD_FILES+=usr/lib/libgeom_p.a -OLD_FILES+=usr/lib/libgnuregex_p.a OLD_FILES+=usr/lib/libgpio_p.a OLD_FILES+=usr/lib/libgssapi_krb5_p.a OLD_FILES+=usr/lib/libgssapi_ntlm_p.a Index: tools/build/options/WITHOUT_BSD_GREP =================================================================== --- tools/build/options/WITHOUT_BSD_GREP +++ /dev/null @@ -1,2 +0,0 @@ -.\" $FreeBSD$ -Install GNU grep as '[ef]grep' instead of BSD grep. Index: tools/build/options/WITHOUT_GNU_GREP =================================================================== --- tools/build/options/WITHOUT_GNU_GREP +++ /dev/null @@ -1,3 +0,0 @@ -.\" $FreeBSD$ -Set to not build GNU -.Xr grep 1 . Index: tools/build/options/WITH_BSD_GREP =================================================================== --- tools/build/options/WITH_BSD_GREP +++ /dev/null @@ -1,2 +0,0 @@ -.\" $FreeBSD$ -Install BSD-licensed grep as '[ef]grep' instead of GNU grep. Index: tools/build/options/WITH_GNU_GREP =================================================================== --- tools/build/options/WITH_GNU_GREP +++ /dev/null @@ -1,3 +0,0 @@ -.\" $FreeBSD$ -Build and install GNU -.Xr grep 1 . Index: usr.bin/grep/Makefile =================================================================== --- usr.bin/grep/Makefile +++ usr.bin/grep/Makefile @@ -4,17 +4,9 @@ .include -.if ${MK_BSD_GREP} == "yes" || defined(BOOTSTRAPPING) PROG= grep MAN1= grep.1 zgrep.1 -.else -PROG= bsdgrep -CLEANFILES+= bsdgrep.1 -MAN1= bsdgrep.1 zgrep.1 -bsdgrep.1: grep.1 - ${CP} ${.ALLSRC} ${.TARGET} -.endif SRCS= file.c grep.c queue.c util.c SCRIPTS= zgrep.sh @@ -33,6 +25,10 @@ ${BINDIR}/zgrep ${BINDIR}/zstdegrep \ ${BINDIR}/zgrep ${BINDIR}/zstdegrep +LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \ + ${BINDIR}/grep ${BINDIR}/fgrep \ + ${BINDIR}/grep ${BINDIR}/rgrep \ + MLINKS= zgrep.1 zfgrep.1 \ zgrep.1 zegrep.1 \ zgrep.1 bzgrep.1 \ @@ -48,17 +44,11 @@ zgrep.1 zstdegrep.1 \ zgrep.1 zstdfgrep.1 -CFLAGS.gcc+= --param max-inline-insns-single=500 - -.if ${MK_BSD_GREP} == "yes" || defined(BOOTSTRAPPING) -LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \ - ${BINDIR}/grep ${BINDIR}/fgrep \ - ${BINDIR}/grep ${BINDIR}/rgrep \ +MLINKS+= grep.1 egrep.1 \ + grep.1 fgrep.1 \ + grep.1 rgrep.1 -MLINKS+= grep.1 egrep.1 \ - grep.1 fgrep.1 \ - grep.1 rgrep.1 -.endif +CFLAGS.gcc+= --param max-inline-insns-single=500 .if !defined(BOOTSTRAPPING) LIBADD+= regex Index: usr.bin/grep/tests/grep_freebsd_test.sh =================================================================== --- usr.bin/grep/tests/grep_freebsd_test.sh +++ usr.bin/grep/tests/grep_freebsd_test.sh @@ -28,12 +28,9 @@ # What grep(1) are we working with? # - 0 : bsdgrep -# - 1 : gnu grep 2.51 (base) -# - 2 : gnu grep (ports) +# - 1 : gnu grep (ports) GREP_TYPE_BSD=0 -GREP_TYPE_GNU_FREEBSD=1 -GREP_TYPE_GNU=2 -GREP_TYPE_UNKNOWN=3 +GREP_TYPE_GNU=1 grep_type() { @@ -44,14 +41,7 @@ return $GREP_TYPE_BSD ;; *"GNU grep"*) - case "$grep_version" in - *2.5.1-FreeBSD*) - return $GREP_TYPE_GNU_FREEBSD - ;; - *) - return $GREP_TYPE_GNU - ;; - esac + return $GREP_TYPE_GNU ;; esac atf_fail "unknown grep type: $grep_version" @@ -87,9 +77,6 @@ { grep_type _type=$? - if [ $_type -eq $GREP_TYPE_GNU_FREEBSD ]; then - atf_expect_fail "\\s and \\S are known to be buggy in base gnugrep" - fi atf_check -o save:grep_alnum.out grep -o '[[:alnum:]]' /COPYRIGHT atf_check -o file:grep_alnum.out grep -o '\w' /COPYRIGHT