1f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*               pcregrep program                 *
3f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
4f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
5f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This is a grep program that uses the PCRE regular expression library to do
6f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichits pattern matching. On Unix-like, Windows, and native z/OS systems it can
7f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrecurse into directories, and in z/OS it can handle PDS files.
8f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
9f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichNote that for native z/OS, in addition to defining the NATIVE_ZOS macro, an
10f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichadditional header is required. That header is not included in the main PCRE
11f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdistribution because other apparatus is needed to compile pcregrep for z/OS.
12f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichThe header can be found in the special z/OS distribution, which is available
13f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfrom www.zaconsultants.net or from www.cbttape.org.
14f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
15f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           Copyright (c) 1997-2014 University of Cambridge
16f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
17f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich-----------------------------------------------------------------------------
18f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichRedistribution and use in source and binary forms, with or without
19f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmodification, are permitted provided that the following conditions are met:
20f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
21f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    * Redistributions of source code must retain the above copyright notice,
22f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      this list of conditions and the following disclaimer.
23f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
24f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    * Redistributions in binary form must reproduce the above copyright
25f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      notice, this list of conditions and the following disclaimer in the
26f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      documentation and/or other materials provided with the distribution.
27f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
28f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    * Neither the name of the University of Cambridge nor the names of its
29f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      contributors may be used to endorse or promote products derived from
30f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      this software without specific prior written permission.
31f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
32f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
36f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichPOSSIBILITY OF SUCH DAMAGE.
43f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich-----------------------------------------------------------------------------
44f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
45f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
46f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef HAVE_CONFIG_H
47f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include "config.h"
48f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
49f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
50f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <ctype.h>
51f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <locale.h>
52f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <stdio.h>
53f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <string.h>
54f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <stdlib.h>
55f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <errno.h>
56f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
57f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <sys/types.h>
58f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <sys/stat.h>
59f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
60f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef HAVE_UNISTD_H
61f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <unistd.h>
62f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
63f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
64f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
65f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <zlib.h>
66f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
67f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
68f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
69f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <bzlib.h>
70f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
71f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
72f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include "pcre.h"
73f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
74f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FALSE 0
75f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define TRUE 1
76f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
77f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef int BOOL;
78f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
79f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define OFFSET_SIZE 99
80f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
81f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if BUFSIZ > 8192
82f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MAXPATLEN BUFSIZ
83f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
84f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define MAXPATLEN 8192
85f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
86f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
87f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define PATBUFSIZE (MAXPATLEN + 10)   /* Allows for prefix+suffix */
88f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
89f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Values for the "filenames" variable, which specifies options for file name
90f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichoutput. The order is important; it is assumed that a file name is wanted for
91f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichall values greater than FN_DEFAULT. */
92f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
93f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { FN_NONE, FN_DEFAULT, FN_MATCH_ONLY, FN_NOMATCH_ONLY, FN_FORCE };
94f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
95f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* File reading styles */
96f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
97f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { FR_PLAIN, FR_LIBZ, FR_LIBBZ2 };
98f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
99f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Actions for the -d and -D options */
100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { dee_READ, dee_SKIP, dee_RECURSE };
102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { DEE_READ, DEE_SKIP };
103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Actions for special processing options (flag bits) */
105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define PO_WORD_MATCH     0x0001
107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define PO_LINE_MATCH     0x0002
108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define PO_FIXED_STRINGS  0x0004
109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Line ending types */
111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Binary file options */
115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT };
117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some
119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenvironments), a warning is issued if the value of fwrite() is ignored.
120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichUnfortunately, casting to (void) does not suppress the warning. To get round
121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthis, we use a macro that compiles a fudge. Oddly, this does not also seem to
122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichapply to fprintf(). */
123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {}
125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*               Global variables                 *
130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Jeffrey Friedl has some debugging requirements that are not part of the
133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichregular code. */
134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int S_arg = -1;
137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic unsigned int jfriedl_XR = 0; /* repeat regex attempt this many times */
138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic unsigned int jfriedl_XT = 0; /* replicate text this many times */
139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const char *jfriedl_prefix = "";
140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const char *jfriedl_postfix = "";
141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int  endlinetype;
144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *colour_string = (char *)"1;31";
146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *colour_option = NULL;
147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *dee_option = NULL;
148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *DEE_option = NULL;
149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *locale = NULL;
150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *main_buffer = NULL;
151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *newline = NULL;
152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *om_separator = (char *)"";
153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *stdin_name = (char *)"(standard input)";
154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const unsigned char *pcretables = NULL;
156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int after_context = 0;
158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int before_context = 0;
159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int binary_files = BIN_BINARY;
160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int both_context = 0;
161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int bufthird = PCREGREP_BUFSIZE;
162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int bufsize = 3*PCREGREP_BUFSIZE;
163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H
165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int dee_action = dee_SKIP;
166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int dee_action = dee_READ;
168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int DEE_action = DEE_READ;
171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int error_count = 0;
172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int filenames = FN_DEFAULT;
173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int pcre_options = 0;
174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int process_options = 0;
175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int study_options = PCRE_STUDY_JIT_COMPILE;
178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int study_options = 0;
180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic unsigned long int match_limit = 0;
183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic unsigned long int match_limit_recursion = 0;
184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL count_only = FALSE;
186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL do_colour = FALSE;
187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL file_offsets = FALSE;
188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL hyphenpending = FALSE;
189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL invert = FALSE;
190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL line_buffered = FALSE;
191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL line_offsets = FALSE;
192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL multiline = FALSE;
193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL number = FALSE;
194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL omit_zero_count = FALSE;
195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL resource_error = FALSE;
196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL quiet = FALSE;
197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL show_only_matching = FALSE;
198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL silent = FALSE;
199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL utf8 = FALSE;
200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for list of --only-matching capturing numbers. */
202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct omstr {
204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  struct omstr *next;
205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int groupnum;
206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} omstr;
207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic omstr *only_matching = NULL;
209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic omstr *only_matching_last = NULL;
210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for holding the two variables that describe a number chain. */
212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct omdatastr {
214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  omstr **anchor;
215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  omstr **lastptr;
216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} omdatastr;
217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic omdatastr only_matching_data = { &only_matching, &only_matching_last };
219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for list of file names (for -f and --{in,ex}clude-from) */
221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct fnstr {
223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  struct fnstr *next;
224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *name;
225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} fnstr;
226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *exclude_from = NULL;
228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *exclude_from_last = NULL;
229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *include_from = NULL;
230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *include_from_last = NULL;
231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *file_lists = NULL;
233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *file_lists_last = NULL;
234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *pattern_files = NULL;
235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fnstr *pattern_files_last = NULL;
236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for holding the two variables that describe a file name chain. */
238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct fndatastr {
240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fnstr **anchor;
241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fnstr **lastptr;
242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} fndatastr;
243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fndatastr exclude_from_data = { &exclude_from, &exclude_from_last };
245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fndatastr include_from_data = { &include_from, &include_from_last };
246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fndatastr file_lists_data = { &file_lists, &file_lists_last };
247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic fndatastr pattern_files_data = { &pattern_files, &pattern_files_last };
248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for pattern and its compiled form; used for matching patterns and
250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichalso for include/exclude patterns. */
251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct patstr {
253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  struct patstr *next;
254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *string;
255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre *compiled;
256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_extra *hint;
257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} patstr;
258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *patterns = NULL;
260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *patterns_last = NULL;
261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *include_patterns = NULL;
262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *include_patterns_last = NULL;
263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *exclude_patterns = NULL;
264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *exclude_patterns_last = NULL;
265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *include_dir_patterns = NULL;
266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *include_dir_patterns_last = NULL;
267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *exclude_dir_patterns = NULL;
268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *exclude_dir_patterns_last = NULL;
269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure holding the two variables that describe a pattern chain. A pointer
271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichto such structures is used for each appropriate option. */
272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct patdatastr {
274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patstr **anchor;
275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patstr **lastptr;
276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} patdatastr;
277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patdatastr match_patdata = { &patterns, &patterns_last };
279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patdatastr include_patdata = { &include_patterns, &include_patterns_last };
280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patdatastr exclude_patdata = { &exclude_patterns, &exclude_patterns_last };
281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patdatastr include_dir_patdata = { &include_dir_patterns, &include_dir_patterns_last };
282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patdatastr exclude_dir_patdata = { &exclude_dir_patterns, &exclude_dir_patterns_last };
283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr **incexlist[4] = { &include_patterns, &exclude_patterns,
285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                                 &include_dir_patterns, &exclude_dir_patterns };
286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const char *incexname[4] = { "--include", "--exclude",
288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                                    "--include-dir", "--exclude-dir" };
289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Structure for options and list of them */
291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichenum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,
293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       OP_OP_NUMBER, OP_OP_NUMBERS, OP_PATLIST, OP_FILELIST, OP_BINFILES };
294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct option_item {
296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int type;
297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int one_char;
298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  void *dataptr;
299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  const char *long_name;
300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  const char *help_text;
301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} option_item;
302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Options without a single-letter equivalent get a negative value. This can be
304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichused to identify them. */
305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_COLOUR       (-1)
307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_EXCLUDE      (-2)
308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_EXCLUDE_DIR  (-3)
309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_HELP         (-4)
310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_INCLUDE      (-5)
311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_INCLUDE_DIR  (-6)
312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_LABEL        (-7)
313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_LOCALE       (-8)
314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_NULL         (-9)
315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_LOFFSETS     (-10)
316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_FOFFSETS     (-11)
317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_LBUFFER      (-12)
318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_M_LIMIT      (-13)
319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_M_LIMIT_REC  (-14)
320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_BUFSIZE      (-15)
321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_NOJIT        (-16)
322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_FILE_LIST    (-17)
323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_BINARY_FILES (-18)
324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_EXCLUDE_FROM (-19)
325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_INCLUDE_FROM (-20)
326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define N_OM_SEPARATOR (-21)
327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic option_item optionlist[] = {
329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_NULL,   NULL,              "",              "terminate options" },
330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_HELP,   NULL,              "help",          "display this help and exit" },
331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NUMBER,     'A',      &after_context,    "after-context=number", "set number of following context lines" },
332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'a',      NULL,              "text",          "treat binary files as text" },
333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NUMBER,     'B',      &before_context,   "before-context=number", "set number of prior context lines" },
334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_BINFILES,   N_BINARY_FILES, NULL,        "binary-files=word", "set treatment of binary files" },
335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NUMBER,     N_BUFSIZE,&bufthird,         "buffer-size=number", "set processing buffer size parameter" },
336f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_OP_STRING,  N_COLOUR, &colour_option,    "color=option",  "matched text color option" },
337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_OP_STRING,  N_COLOUR, &colour_option,    "colour=option", "matched text colour option" },
338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NUMBER,     'C',      &both_context,     "context=number", "set number of context lines, before & after" },
339f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'c',      NULL,              "count",         "print only a count of matching lines per FILE" },
340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     'D',      &DEE_option,       "devices=action","how to handle devices, FIFOs, and sockets" },
341f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     'd',      &dee_option,       "directories=action", "how to handle directories" },
342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,    'e',      &match_patdata,    "regex(p)=pattern", "specify pattern (may be used more than once)" },
343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'F',      NULL,              "fixed-strings", "patterns are sets of newline-separated strings" },
344f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_FILELIST,   'f',      &pattern_files_data, "file=path",   "read patterns from file" },
345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_FILELIST,   N_FILE_LIST, &file_lists_data, "file-list=path","read files to search from file" },
346f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_FOFFSETS, NULL,            "file-offsets",  "output file offsets, not text" },
347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'H',      NULL,              "with-filename", "force the prefixing filename on output" },
348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'h',      NULL,              "no-filename",   "suppress the prefixing filename on output" },
349f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'I',      NULL,              "",              "treat binary files as not matching (ignore)" },
350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'i',      NULL,              "ignore-case",   "ignore case distinctions" },
351f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "do not use just-in-time compiler optimization" },
353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
354f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_NOJIT,  NULL,              "no-jit",        "ignored: this pcregrep does not support JIT" },
355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
356f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'l',      NULL,              "files-with-matches", "print only FILE names containing matches" },
357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'L',      NULL,              "files-without-match","print only FILE names not containing matches" },
358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     N_LABEL,  &stdin_name,       "label=name",    "set name for standard input" },
359f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_LBUFFER, NULL,             "line-buffered", "use line buffering" },
360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     N_LOFFSETS, NULL,            "line-offsets",  "output line numbers and offsets, not text" },
361f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     N_LOCALE, &locale,           "locale=locale", "use the named locale" },
362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_LONGNUMBER, N_M_LIMIT, &match_limit,     "match-limit=number", "set PCRE match limit option" },
363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_LONGNUMBER, N_M_LIMIT_REC, &match_limit_recursion, "recursion-limit=number", "set PCRE match recursion limit option" },
364f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'M',      NULL,              "multiline",     "run in multiline mode" },
365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     'N',      &newline,          "newline=type",  "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" },
366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'n',      NULL,              "line-number",   "print line number with output lines" },
367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_OP_NUMBERS, 'o',      &only_matching_data, "only-matching=n", "show only the part of the line that matched" },
368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_STRING,     N_OM_SEPARATOR, &om_separator, "om-separator=text", "set separator for multiple -o output" },
369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'q',      NULL,              "quiet",         "suppress output, just set return code" },
370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,     'r',      NULL,              "recursive",     "recursively scan sub-directories" },
371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,    N_EXCLUDE,&exclude_patdata,  "exclude=pattern","exclude matching files when recursing" },
372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,    N_INCLUDE,&include_patdata,  "include=pattern","include matching files when recursing" },
373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,    N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude-dir=pattern","exclude matching directories when recursing" },
374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,    N_INCLUDE_DIR,&include_dir_patdata, "include-dir=pattern","include matching directories when recursing" },
375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_FILELIST,   N_EXCLUDE_FROM,&exclude_from_data, "exclude-from=path", "read exclude list from file" },
376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_FILELIST,   N_INCLUDE_FROM,&include_from_data, "include-from=path", "read include list from file" },
377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* These two were accidentally implemented with underscores instead of
379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  hyphens in the option names. As this was not discovered for several releases,
380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  the incorrect versions are left in the table for compatibility. However, the
381f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  --help function misses out any option that has an underscore in its name. */
382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,   N_EXCLUDE_DIR,&exclude_dir_patdata, "exclude_dir=pattern","exclude matching directories when recursing" },
384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_PATLIST,   N_INCLUDE_DIR,&include_dir_patdata, "include_dir=pattern","include matching directories when recursing" },
385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_OP_NUMBER, 'S',      &S_arg,            "jeffS",         "replace matched (sub)string with X" },
388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    's',      NULL,              "no-messages",   "suppress error messages" },
390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    'u',      NULL,              "utf-8",         "use UTF-8 mode" },
391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    'V',      NULL,              "version",       "print version information and exit" },
392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    'v',      NULL,              "invert-match",  "select non-matching lines" },
393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    'w',      NULL,              "word-regex(p)", "force patterns to match only as words"  },
394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    'x',      NULL,              "line-regex(p)", "force patterns to match only whole lines" },
395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  { OP_NODATA,    0,        NULL,               NULL,            NULL }
396f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich};
397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Tables for prefixing and suffixing patterns, according to the -w, -x, and -F
399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichoptions. These set the 1, 2, and 4 bits in process_options, respectively. Note
400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthat the combination of -w and -x has the same effect as -x on its own, so we
401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichcan treat them as the same. Note that the MAXPATLEN macro assumes the longest
402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprefix+suffix is 10 characters; if anything longer is added, it must be
403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichadjusted. */
404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const char *prefix[] = {
406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  "", "\\b", "^(?:", "^(?:", "\\Q", "\\b\\Q", "^(?:\\Q", "^(?:\\Q" };
407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic const char *suffix[] = {
409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  "", "\\b", ")$",   ")$",   "\\E", "\\E\\b", "\\E)$",   "\\E)$" };
410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* UTF-8 tables - used only when the newline setting is "any". */
412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
413f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
414f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
415f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst char utf8_table4[] = {
416f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*         Exit from the program                  *
425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If there has been a resource error, give a suitable message.
428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArgument:  the return code
430f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:   does not return
431f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
432f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
433f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcregrep_exit(int rc)
435f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (resource_error)
437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
438f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit "
439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT,
440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    PCRE_ERROR_JIT_STACKLIMIT);
441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n");
442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichexit(rc);
444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*          Add item to chain of patterns         *
449f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Used to add an item onto a chain, or just return an unconnected item if the
452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich"after" argument is NULL.
453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  s          pattern string to add
456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  after      if not NULL points to item to insert after
457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:     new pattern block or NULL on error
459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic patstr *
462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichadd_pattern(char *s, patstr *after)
463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpatstr *p = (patstr *)malloc(sizeof(patstr));
465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (p == NULL)
466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: malloc failed\n");
468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(2);
469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
470f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (strlen(s) > MAXPATLEN)
471f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
472f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: pattern is too long (limit is %d bytes)\n",
473f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    MAXPATLEN);
474f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  free(p);
475f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return NULL;
476f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
477f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichp->next = NULL;
478f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichp->string = s;
479f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichp->compiled = NULL;
480f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichp->hint = NULL;
481f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
482f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (after != NULL)
483f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
484f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p->next = after->next;
485f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  after->next = p;
486f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
487f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn p;
488f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
489f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
490f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
491f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
492f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*           Free chain of patterns               *
493f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
494f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
495f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Used for several chains of patterns.
496f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
497f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArgument: pointer to start of chain
498f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:  nothing
499f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
500f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
501f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
502f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(patstr *pc)
503f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
504f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (pc != NULL)
505f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
506f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patstr *p = pc;
507f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pc = p->next;
508f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (p->hint != NULL) pcre_free_study(p->hint);
509f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (p->compiled != NULL) pcre_free(p->compiled);
510f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  free(p);
511f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
512f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
513f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
514f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
515f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
516f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*           Free chain of file names             *
517f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
518f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
519f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*
520f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArgument: pointer to start of chain
521f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:  nothing
522f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
523f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
524f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
525f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_file_chain(fnstr *fn)
526f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
527f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (fn != NULL)
528f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
529f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fnstr *f = fn;
530f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fn = f->next;
531f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  free(f);
532f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
533f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
534f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
535f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
536f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
537f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*            OS-specific functions               *
538f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
539f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
540f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* These functions are defined so that they can be made system specific.
541f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichAt present there are versions for Unix-style environments, Windows, native
542f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichz/OS, and "no support". */
543f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
544f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
545f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Directory scanning Unix-style and z/OS ***********/
546f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
547f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined HAVE_SYS_STAT_H && defined HAVE_DIRENT_H && defined HAVE_SYS_TYPES_H) || defined NATIVE_ZOS
548f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <sys/types.h>
549f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <sys/stat.h>
550f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <dirent.h>
551f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
552f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
553f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Directory and PDS/E scanning for z/OS ***********/
554f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* z/OS looks mostly like Unix with USS ************/
555f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* However, z/OS needs the #include statements in this header */
556f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include "pcrzosfs.h"
557f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* That header is not included in the main PCRE distribution because
558f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   other apparatus is needed to compile pcregrep for z/OS. The header
559f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   can be found in the special z/OS distribution, which is available
560f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   from www.zaconsultants.net or from www.cbttape.org. */
561f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
562f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
563f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef DIR directory_type;
564f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FILESEP '/'
565f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
566f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
567f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichisdirectory(char *filename)
568f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
569f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstruct stat statbuf;
570f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (stat(filename, &statbuf) < 0)
571f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 0;        /* In the expectation that opening as a file will fail */
572f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn (statbuf.st_mode & S_IFMT) == S_IFDIR;
573f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
574f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
575f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic directory_type *
576f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichopendirectory(char *filename)
577f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
578f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn opendir(filename);
579f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
580f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
581f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *
582f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreaddirectory(directory_type *dir)
583f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
584f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (;;)
585f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
586f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  struct dirent *dent = readdir(dir);
587f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (dent == NULL) return NULL;
588f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0)
589f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return dent->d_name;
590f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
591f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Control never reaches here */
592f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
593f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
594f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
595f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichclosedirectory(directory_type *dir)
596f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
597f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichclosedir(dir);
598f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
599f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
600f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
601f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for regular file, Unix-style **********/
602f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
603f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
604f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichisregfile(char *filename)
605f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
606f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstruct stat statbuf;
607f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (stat(filename, &statbuf) < 0)
608f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 1;        /* In the expectation that opening as a file will fail */
609f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn (statbuf.st_mode & S_IFMT) == S_IFREG;
610f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
611f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
612f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
613f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
614f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for a terminal in z/OS **********/
615f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* isatty() does not work in a TSO environment, so always give FALSE.*/
616f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
617f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
618f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_stdout_tty(void)
619f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
620f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
621f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
622f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
623f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
624f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_file_tty(FILE *f)
625f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
626f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
627f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
628f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
629f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
630f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for a terminal, Unix-style **********/
631f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
632f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
633f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
634f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_stdout_tty(void)
635f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
636f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn isatty(fileno(stdout));
637f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
638f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
639f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
640f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_file_tty(FILE *f)
641f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
642f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn isatty(fileno(f));
643f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
644f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
645f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
646f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* End of Unix-style or native z/OS environment functions. */
647f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
648f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
649f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Directory scanning in Windows ***********/
650f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
651f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* I (Philip Hazel) have no means of testing this code. It was contributed by
652f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichLionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
653f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhen it did not exist. David Byron added a patch that moved the #include of
654f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich<windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
655f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichThe double test below stops gcc 4.4.4 grumbling that HAVE_WINDOWS_H is
656f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichundefined when it is indeed undefined. */
657f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
658f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#elif defined HAVE_WINDOWS_H && HAVE_WINDOWS_H
659f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
660f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef STRICT
661f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# define STRICT
662f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
663f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef WIN32_LEAN_AND_MEAN
664f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich# define WIN32_LEAN_AND_MEAN
665f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
666f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
667f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#include <windows.h>
668f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
669f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef INVALID_FILE_ATTRIBUTES
670f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
671f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
672f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
673f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef struct directory_type
674f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
675f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichHANDLE handle;
676f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBOOL first;
677f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichWIN32_FIND_DATA data;
678f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} directory_type;
679f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
680f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FILESEP '/'
681f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
682f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint
683f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichisdirectory(char *filename)
684f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
685f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichDWORD attr = GetFileAttributes(filename);
686f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (attr == INVALID_FILE_ATTRIBUTES)
687f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 0;
688f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
689f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
690f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
691f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdirectory_type *
692f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichopendirectory(char *filename)
693f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
694f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichsize_t len;
695f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *pattern;
696f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdirectory_type *dir;
697f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichDWORD err;
698f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichlen = strlen(filename);
699f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpattern = (char *)malloc(len + 3);
700f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdir = (directory_type *)malloc(sizeof(*dir));
701f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif ((pattern == NULL) || (dir == NULL))
702f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
703f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: malloc failed\n");
704f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(2);
705f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
706f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmemcpy(pattern, filename, len);
707f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmemcpy(&(pattern[len]), "\\*", 3);
708f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdir->handle = FindFirstFile(pattern, &(dir->data));
709f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (dir->handle != INVALID_HANDLE_VALUE)
710f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
711f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  free(pattern);
712f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  dir->first = TRUE;
713f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return dir;
714f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
715f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevicherr = GetLastError();
716f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree(pattern);
717f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree(dir);
718f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevicherrno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT;
719f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn NULL;
720f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
721f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
722f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *
723f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreaddirectory(directory_type *dir)
724f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
725f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (;;)
726f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
727f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!dir->first)
728f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
729f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (!FindNextFile(dir->handle, &(dir->data)))
730f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return NULL;
731f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
732f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
733f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
734f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    dir->first = FALSE;
735f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
736f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0)
737f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return dir->data.cFileName;
738f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
739f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef _MSC_VER
740f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn NULL;   /* Keep compiler happy; never executed */
741f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
742f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
743f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
744f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichvoid
745f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichclosedirectory(directory_type *dir)
746f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
747f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichFindClose(dir->handle);
748f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree(dir);
749f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
750f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
751f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
752f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for regular file in Windows **********/
753f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
754f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* I don't know how to do this, or if it can be done; assume all paths are
755f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichregular if they are not directories. */
756f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
757f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint isregfile(char *filename)
758f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
759f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn !isdirectory(filename);
760f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
761f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
762f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
763f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for a terminal in Windows **********/
764f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
765f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* I don't know how to do this; assume never */
766f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
767f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
768f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_stdout_tty(void)
769f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
770f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
771f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
772f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
773f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
774f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_file_tty(FILE *f)
775f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
776f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
777f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
778f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
779f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* End of Windows functions */
780f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
781f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
782f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Directory scanning when we can't do it ***********/
783f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
784f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* The type is void, and apart from isdirectory(), the functions do nothing. */
785f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
786f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
787f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
788f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define FILESEP 0
789f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtypedef void directory_type;
790f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
791f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint isdirectory(char *filename) { return 0; }
792f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdirectory_type * opendirectory(char *filename) { return (directory_type*)0;}
793f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *readdirectory(directory_type *dir) { return (char*)0;}
794f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichvoid closedirectory(directory_type *dir) {}
795f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
796f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
797f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for regular file when we can't do it **********/
798f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
799f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Assume all files are regular. */
800f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
801f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint isregfile(char *filename) { return 1; }
802f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
803f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
804f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/************* Test for a terminal when we can't do it **********/
805f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
806f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
807f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_stdout_tty(void)
808f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
809f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
810f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
811f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
812f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
813f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis_file_tty(FILE *f)
814f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
815f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
816f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
817f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
818f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif  /* End of system-specific functions */
819f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
820f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
821f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
822f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef HAVE_STRERROR
823f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
824f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*     Provide strerror() for non-ANSI libraries  *
825f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
826f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
827f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
828f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichin their libraries, but can provide the same facility by this simple
829f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichalternative function. */
830f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
831f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichextern int   sys_nerr;
832f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichextern char *sys_errlist[];
833f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
834f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *
835f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstrerror(int n)
836f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
837f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (n < 0 || n >= sys_nerr) return "unknown error number";
838f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn sys_errlist[n];
839f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
840f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif /* HAVE_STRERROR */
841f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
842f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
843f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
844f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
845f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*                Usage function                  *
846f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
847f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
848f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
849f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichusage(int rc)
850f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
851f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichoption_item *op;
852f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfprintf(stderr, "Usage: pcregrep [-");
853f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (op = optionlist; op->one_char != 0; op++)
854f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
855f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (op->one_char > 0) fprintf(stderr, "%c", op->one_char);
856f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
857f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfprintf(stderr, "] [long options] [pattern] [files]\n");
858f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfprintf(stderr, "Type `pcregrep --help' for more information and the long "
859f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  "options.\n");
860f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn rc;
861f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
862f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
863f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
864f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
865f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
866f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*                Help function                   *
867f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
868f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
869f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
870f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichhelp(void)
871f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
872f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichoption_item *op;
873f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
874f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n");
875f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Search for PATTERN in each FILE or standard input.\n");
876f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("PATTERN must be present if neither -e nor -f is used.\n");
877f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("\"-\" can be used as a file name to mean STDIN.\n");
878f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
879f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
880f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Files whose names end in .gz are read using zlib.\n");
881f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
882f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
883f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
884f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Files whose names end in .bz2 are read using bzlib2.\n");
885f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
886f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
887f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
888f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Other files and the standard input are read as plain files.\n\n");
889f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else
890f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("All files are read as plain files, without any interpretation.\n\n");
891f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
892f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
893f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n");
894f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Options:\n");
895f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
896f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (op = optionlist; op->one_char != 0; op++)
897f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
898f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int n;
899f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char s[4];
900f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
901f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Two options were accidentally implemented and documented with underscores
902f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  instead of hyphens in their names, something that was not noticed for quite a
903f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  few releases. When fixing this, I left the underscored versions in the list
904f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  in case people were using them. However, we don't want to display them in the
905f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  help data. There are no other options that contain underscores, and we do not
906f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  expect ever to implement such options. Therefore, just omit any option that
907f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  contains an underscore. */
908f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
909f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strchr(op->long_name, '_') != NULL) continue;
910f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
911f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (op->one_char > 0 && (op->long_name)[0] == 0)
912f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    n = 31 - printf("  -%c", op->one_char);
913f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
914f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
915f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (op->one_char > 0) sprintf(s, "-%c,", op->one_char);
916f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else strcpy(s, "   ");
917f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    n = 31 - printf("  %s --%s", s, op->long_name);
918f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
919f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
920f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (n < 1) n = 1;
921f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  printf("%.*s%s\n", n, "                           ", op->help_text);
922f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
923f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
924f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");
925f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);
926f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("When reading patterns or file names from a file, trailing white\n");
927f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("space is removed and blank lines are ignored.\n");
928f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("The maximum size of any pattern is %d bytes.\n", MAXPATLEN);
929f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
930f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");
931f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprintf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");
932f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
933f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
934f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
935f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
936f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
937f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*            Test exclude/includes               *
938f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
939f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
940f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If any exclude pattern matches, the path is excluded. Otherwise, unless
941f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthere are no includes, the path must match an include pattern.
942f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
943f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
944f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  path      the path to be matched
945f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ip        the chain of include patterns
946f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ep        the chain of exclude patterns
947f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
948f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:    TRUE if the path is not excluded
949f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
950f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
951f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
952f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtest_incexc(char *path, patstr *ip, patstr *ep)
953f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
954f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint plen = strlen(path);
955f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
956f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (; ep != NULL; ep = ep->next)
957f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
958f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (pcre_exec(ep->compiled, NULL, path, plen, 0, 0, NULL, 0) >= 0)
959f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return FALSE;
960f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
961f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
962f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (ip == NULL) return TRUE;
963f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
964f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (; ip != NULL; ip = ip->next)
965f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
966f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (pcre_exec(ip->compiled, NULL, path, plen, 0, 0, NULL, 0) >= 0)
967f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return TRUE;
968f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
969f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
970f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
971f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
972f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
973f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
974f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
975f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
976f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*         Decode integer argument value          *
977f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
978f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
979f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Integer arguments can be followed by K or M. Avoid the use of strtoul()
980f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbecause SunOS4 doesn't have it. This is used only for unpicking arguments, so
981f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichjust keep it simple.
982f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
983f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
984f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  option_data   the option data string
985f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  op            the option item (for error messages)
986f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  longop        TRUE if option given in long form
987f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
988f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:        a long integer
989f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
990f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
991f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic long int
992f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdecode_number(char *option_data, option_item *op, BOOL longop)
993f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
994f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichunsigned long int n = 0;
995f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *endptr = option_data;
996f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;
997f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (isdigit((unsigned char)(*endptr)))
998f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  n = n * 10 + (int)(*endptr++ - '0');
999f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (toupper(*endptr) == 'K')
1000f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1001f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  n *= 1024;
1002f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endptr++;
1003f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1004f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (toupper(*endptr) == 'M')
1005f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1006f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  n *= 1024*1024;
1007f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endptr++;
1008f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1009f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1010f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (*endptr != 0)   /* Error */
1011f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1012f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (longop)
1013f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1014f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *equals = strchr(op->long_name, '=');
1015f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int nlen = (equals == NULL)? (int)strlen(op->long_name) :
1016f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      (int)(equals - op->long_name);
1017f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Malformed number \"%s\" after --%.*s\n",
1018f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      option_data, nlen, op->long_name);
1019f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1020f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
1021f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Malformed number \"%s\" after -%c\n",
1022f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      option_data, op->one_char);
1023f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(usage(2));
1024f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1025f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1026f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn n;
1027f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1028f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1029f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1030f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1031f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1032f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*       Add item to a chain of numbers           *
1033f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1034f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1035f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Used to add an item onto a chain, or just return an unconnected item if the
1036f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich"after" argument is NULL.
1037f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1038f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1039f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  n          the number to add
1040f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  after      if not NULL points to item to insert after
1041f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1042f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:     new number block
1043f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1044f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1045f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic omstr *
1046f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichadd_number(int n, omstr *after)
1047f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1048f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichomstr *om = (omstr *)malloc(sizeof(omstr));
1049f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1050f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (om == NULL)
1051f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1052f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: malloc failed\n");
1053f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(2);
1054f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1055f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichom->next = NULL;
1056f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichom->groupnum = n;
1057f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1058f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (after != NULL)
1059f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1060f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  om->next = after->next;
1061f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  after->next = om;
1062f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1063f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn om;
1064f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1065f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1066f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1067f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1068f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1069f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*            Read one line of input              *
1070f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1071f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1072f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Normally, input is read using fread() into a large buffer, so many lines may
1073f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbe read at once. However, doing this for tty input means that no output appears
1074f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichuntil a lot of input has been typed. Instead, tty input is handled line by
1075f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichline. We cannot use fgets() for this, because it does not stop at a binary
1076f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichzero, and therefore there is no way of telling how many characters it has read,
1077f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbecause there may be binary zeros embedded in the data.
1078f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1079f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1080f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  buffer     the buffer to read into
1081f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  length     the maximum number of characters to read
1082f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  f          the file
1083f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1084f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:     the number of characters read, zero at end of file
1085f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1086f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1087f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic unsigned int
1088f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichread_one_line(char *buffer, int length, FILE *f)
1089f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1090f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint c;
1091f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint yield = 0;
1092f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile ((c = fgetc(f)) != EOF)
1093f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1094f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  buffer[yield++] = c;
1095f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (c == '\n' || yield >= length) break;
1096f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1097f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn yield;
1098f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1099f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*             Find end of line                   *
1104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* The length of the endline sequence that is found is set via lenptr. This may
1107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbe zero at the very end of the file if there is no line-ending sequence there.
1108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p         current position in line
1111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endptr    end of available data
1112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  lenptr    where to put the length of the eol sequence
1113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:    pointer after the last byte of the line,
1115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            including the newline byte(s)
1116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *
1119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichend_of_line(char *p, char *endptr, int *lenptr)
1120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichswitch(endlinetype)
1122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  default:      /* Just in case */
1124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_LF:
1125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p < endptr && *p != '\n') p++;
1126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (p < endptr)
1127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *lenptr = 1;
1129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return p + 1;
1130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *lenptr = 0;
1132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return endptr;
1133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_CR:
1135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p < endptr && *p != '\r') p++;
1136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (p < endptr)
1137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *lenptr = 1;
1139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return p + 1;
1140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *lenptr = 0;
1142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return endptr;
1143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_CRLF:
1145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  for (;;)
1146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while (p < endptr && *p != '\r') p++;
1148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (++p >= endptr)
1149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = 0;
1151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return endptr;
1152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*p == '\n')
1154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = 2;
1156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p + 1;
1157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  break;
1160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_ANYCRLF:
1162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p < endptr)
1163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int extra = 0;
1165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    register int c = *((unsigned char *)p);
1166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (utf8 && c >= 0xc0)
1168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      int gcii, gcss;
1170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
1171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      gcss = 6*extra;
1172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      c = (c & utf8_table3[extra]) << gcss;
1173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      for (gcii = 1; gcii <= extra; gcii++)
1174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        gcss -= 6;
1176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        c |= (p[gcii] & 0x3f) << gcss;
1177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    p += 1 + extra;
1181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    switch (c)
1183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\n':
1185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = 1;
1186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\r':
1189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (p < endptr && *p == '\n')
1190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        *lenptr = 2;
1192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        p++;
1193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else *lenptr = 1;
1195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      default:
1198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
1199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }   /* End of loop for ANYCRLF case */
1201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *lenptr = 0;  /* Must have hit the end */
1203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return endptr;
1204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_ANY:
1206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p < endptr)
1207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int extra = 0;
1209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    register int c = *((unsigned char *)p);
1210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (utf8 && c >= 0xc0)
1212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      int gcii, gcss;
1214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
1215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      gcss = 6*extra;
1216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      c = (c & utf8_table3[extra]) << gcss;
1217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      for (gcii = 1; gcii <= extra; gcii++)
1218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        gcss -= 6;
1220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        c |= (p[gcii] & 0x3f) << gcss;
1221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    p += 1 + extra;
1225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    switch (c)
1227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\n':    /* LF */
1229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\v':    /* VT */
1230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\f':    /* FF */
1231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = 1;
1232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\r':    /* CR */
1235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (p < endptr && *p == '\n')
1236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        *lenptr = 2;
1238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        p++;
1239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else *lenptr = 1;
1241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef EBCDIC
1244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x85:    /* Unicode NEL */
1245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = utf8? 2 : 1;
1246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x2028:  /* Unicode LS */
1249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x2029:  /* Unicode PS */
1250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *lenptr = 3;
1251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif  /* Not EBCDIC */
1253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      default:
1255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
1256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }   /* End of loop for ANY case */
1258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *lenptr = 0;  /* Must have hit the end */
1260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return endptr;
1261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }     /* End of overall switch */
1262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*         Find start of previous line            *
1268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This is called when looking back for before lines to print.
1271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p         start of the subsequent line
1274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  startptr  start of available data
1275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:    pointer to the start of the previous line
1277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *
1280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichprevious_line(char *p, char *startptr)
1281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichswitch(endlinetype)
1283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  default:      /* Just in case */
1285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_LF:
1286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p--;
1287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p > startptr && p[-1] != '\n') p--;
1288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return p;
1289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_CR:
1291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p--;
1292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p > startptr && p[-1] != '\n') p--;
1293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return p;
1294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_CRLF:
1296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  for (;;)
1297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    p -= 2;
1299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while (p > startptr && p[-1] != '\n') p--;
1300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (p <= startptr + 1 || p[-2] == '\r') return p;
1301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Control can never get here */
1303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_ANY:
1305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case EL_ANYCRLF:
1306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*(--p) == '\n' && p > startptr && p[-1] == '\r') p--;
1307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (utf8) while ((*p & 0xc0) == 0x80) p--;
1308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (p > startptr)
1310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    register unsigned int c;
1312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *pp = p - 1;
1313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (utf8)
1315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      int extra = 0;
1317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      while ((*pp & 0xc0) == 0x80) pp--;
1318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      c = *((unsigned char *)pp);
1319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (c >= 0xc0)
1320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int gcii, gcss;
1322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        extra = utf8_table4[c & 0x3f];  /* Number of additional bytes */
1323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        gcss = 6*extra;
1324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        c = (c & utf8_table3[extra]) << gcss;
1325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        for (gcii = 1; gcii <= extra; gcii++)
1326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          gcss -= 6;
1328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          c |= (pp[gcii] & 0x3f) << gcss;
1329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else c = *((unsigned char *)pp);
1333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (endlinetype == EL_ANYCRLF) switch (c)
1335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1336f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\n':    /* LF */
1337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\r':    /* CR */
1338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1339f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      default:
1341f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
1342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1344f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else switch (c)
1345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1346f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\n':    /* LF */
1347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\v':    /* VT */
1348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\f':    /* FF */
1349f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case '\r':    /* CR */
1350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifndef EBCDIE
1351f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x85:    /* Unicode NEL */
1352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x2028:  /* Unicode LS */
1353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 0x2029:  /* Unicode PS */
1354f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif  /* Not EBCDIC */
1355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return p;
1356f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      default:
1358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
1359f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1361f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    p = pp;  /* Back one character */
1362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }        /* End of loop for ANY case */
1363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1364f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return startptr;  /* Hit start of data */
1365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }     /* End of overall switch */
1366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*       Print the previous "after" lines         *
1374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This is called if we are about to lose said lines because of buffer filling,
1377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichand at the end of the file. The data in the line is written using fwrite() so
1378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthat a binary zero does not terminate it.
1379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1381f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  lastmatchnumber   the number of the last matching line, plus one
1382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  lastmatchrestart  where we restarted after the last match
1383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endptr            end of available data
1384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  printname         filename for printing
1385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:            nothing
1387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic void
1390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdo_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr,
1391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *printname)
1392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (after_context > 0 && lastmatchnumber > 0)
1394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int count = 0;
1396f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (lastmatchrestart < endptr && count++ < after_context)
1397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int ellength;
1399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *pp = lastmatchrestart;
1400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (printname != NULL) fprintf(stdout, "%s-", printname);
1401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (number) fprintf(stdout, "%d-", lastmatchnumber++);
1402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    pp = end_of_line(pp, endptr, &ellength);
1403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
1404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    lastmatchrestart = pp;
1405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  hyphenpending = TRUE;
1407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1413f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*   Apply patterns to subject till one matches   *
1414f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1415f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1416f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This function is called to run through all patterns, looking for a match. It
1417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis used multiple times for the same subject when colouring is enabled, in order
1418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichto find all possible matches.
1419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  matchptr     the start of the subject
1422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  length       the length of the subject to match
1423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  options      options for pcre_exec
1424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  startoffset  where to start matching
1425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  offsets      the offets vector to fill in
1426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  mrc          address of where to put the result of pcre_exec()
1427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:      TRUE if there was a match
1429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              FALSE if there was no match
1430f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              invert if there was a non-fatal error
1431f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1432f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1433f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
1434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmatch_patterns(char *matchptr, size_t length, unsigned int options,
1435f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int startoffset, int *offsets, int *mrc)
1436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint i;
1438f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichsize_t slen = length;
1439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpatstr *p = patterns;
1440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst char *msg = "this text:\n\n";
1441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (slen > 200)
1443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  slen = 200;
1445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  msg = "text that starts:\n\n";
1446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (i = 1; p != NULL; p = p->next, i++)
1448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1449f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *mrc = pcre_exec(p->compiled, p->hint, matchptr, (int)length,
1450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    startoffset, options, offsets, OFFSET_SIZE);
1451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*mrc >= 0) return TRUE;
1452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*mrc == PCRE_ERROR_NOMATCH) continue;
1453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);
1454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (patterns->next != NULL) fprintf(stderr, "pattern number %d to ", i);
1455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "%s", msg);
1456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  FWRITE(matchptr, 1, slen, stderr);   /* In case binary zero included */
1457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "\n\n");
1458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT ||
1459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *mrc == PCRE_ERROR_JIT_STACKLIMIT)
1460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    resource_error = TRUE;
1461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (error_count++ > 20)
1462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Too many errors - abandoned.\n");
1464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    pcregrep_exit(2);
1465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return invert;    /* No more matching; don't show the line again */
1467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;  /* No match, no errors */
1470f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
1471f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1472f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1473f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1474f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
1475f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*            Grep an individual file             *
1476f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
1477f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1478f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This is called from grep_or_recurse() below. It uses a buffer that is three
1479f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichtimes the value of bufthird. The matching point is never allowed to stray into
1480f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthe top third of the buffer, thus keeping more of the file available for
1481f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichcontext printing or for multiline scanning. For large files, the pointer will
1482f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbe in the middle third most of the time, so the bottom third is available for
1483f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich"before" context printing.
1484f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1485f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
1486f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  handle       the fopened FILE stream for a normal file
1487f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               the gzFile pointer when reading is via libz
1488f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               the BZFILE pointer when reading is via libbz2
1489f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  frtype       FR_PLAIN, FR_LIBZ, or FR_LIBBZ2
1490f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  filename     the file name or NULL (for errors)
1491f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  printname    the file name if it is to be printed for each match
1492f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               or NULL if the file name is not to be printed
1493f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               it cannot be NULL if filenames[_nomatch]_only is set
1494f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1495f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:       0 if there was at least one match
1496f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               1 otherwise (no matches)
1497f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               2 if an overlong line is encountered
1498f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               3 if there is a read error on a .bz2 file
1499f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
1500f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1501f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
1502f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcregrep(void *handle, int frtype, char *filename, char *printname)
1503f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
1504f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint rc = 1;
1505f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint linenumber = 1;
1506f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint lastmatchnumber = 0;
1507f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint count = 0;
1508f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint filepos = 0;
1509f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint offsets[OFFSET_SIZE];
1510f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *lastmatchrestart = NULL;
1511f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *ptr = main_buffer;
1512f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *endptr;
1513f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichsize_t bufflength;
1514f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBOOL binary = FALSE;
1515f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBOOL endhyphenpending = FALSE;
1516f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBOOL input_line_buffered = line_buffered;
1517f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichFILE *in = NULL;                    /* Ensure initialized */
1518f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1519f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
1520f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichgzFile ingz = NULL;
1521f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1522f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1523f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
1524f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBZFILE *inbz2 = NULL;
1525f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1526f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1527f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1528f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Do the first read into the start of the buffer and set up the pointer to end
1529f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichof what we have. In the case of libz, a non-zipped .gz file will be read as a
1530f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichplain file. However, if a .bz2 file isn't actually bzipped, the first read will
1531f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfail. */
1532f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1533f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich(void)frtype;
1534f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1535f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
1536f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (frtype == FR_LIBZ)
1537f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1538f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ingz = (gzFile)handle;
1539f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  bufflength = gzread (ingz, main_buffer, bufsize);
1540f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1541f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
1542f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1543f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1544f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
1545f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (frtype == FR_LIBBZ2)
1546f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1547f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  inbz2 = (BZFILE *)handle;
1548f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  bufflength = BZ2_bzread(inbz2, main_buffer, bufsize);
1549f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if ((int)bufflength < 0) return 2;   /* Gotcha: bufflength is size_t; */
1550f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }                                    /* without the cast it is unsigned. */
1551f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
1552f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1553f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1554f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1555f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  in = (FILE *)handle;
1556f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (is_file_tty(in)) input_line_buffered = TRUE;
1557f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  bufflength = input_line_buffered?
1558f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    read_one_line(main_buffer, bufsize, in) :
1559f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fread(main_buffer, 1, bufsize, in);
1560f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1561f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1562f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichendptr = main_buffer + bufflength;
1563f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1564f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Unless binary-files=text, see if we have a binary file. This uses the same
1565f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrule as GNU grep, namely, a search for a binary zero byte near the start of the
1566f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfile. */
1567f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1568f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (binary_files != BIN_TEXT)
1569f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1570f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  binary =
1571f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL;
1572f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (binary && binary_files == BIN_NOMATCH) return 1;
1573f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1574f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1575f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Loop while the current pointer is not at the end of the file. For large
1576f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfiles, endptr will be at the end of the buffer when we are in the middle of the
1577f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfile, but ptr will never get there, because as soon as it gets over 2/3 of the
1578f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichway, the buffer is shifted left and re-filled. */
1579f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1580f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (ptr < endptr)
1581f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1582f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int endlinelength;
1583f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int mrc = 0;
1584f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int startoffset = 0;
1585f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  unsigned int options = 0;
1586f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  BOOL match;
1587f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *matchptr = ptr;
1588f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *t = ptr;
1589f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  size_t length, linelength;
1590f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1591f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* At this point, ptr is at the start of a line. We need to find the length
1592f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  of the subject string to pass to pcre_exec(). In multiline mode, it is the
1593f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  length remainder of the data in the buffer. Otherwise, it is the length of
1594f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  the next line, excluding the terminating newline. After matching, we always
1595f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  advance by the length of the next line. In multiline mode the PCRE_FIRSTLINE
1596f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  option is used for compiling, so that any match is constrained to be in the
1597f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  first line. */
1598f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1599f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  t = end_of_line(t, endptr, &endlinelength);
1600f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  linelength = t - ptr - endlinelength;
1601f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  length = multiline? (size_t)(endptr - ptr) : linelength;
1602f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1603f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Check to see if the line we are looking at extends right to the very end
1604f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  of the buffer without a line terminator. This means the line is too long to
1605f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  handle. */
1606f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1607f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (endlinelength == 0 && t == main_buffer + bufsize)
1608f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1609f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n"
1610f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                    "pcregrep: check the --buffer-size option\n",
1611f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                    linenumber,
1612f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                    (filename == NULL)? "" : " of file ",
1613f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                    (filename == NULL)? "" : filename);
1614f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return 2;
1615f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1616f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1617f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Extra processing for Jeffrey Friedl's debugging. */
1618f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1619f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
1620f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (jfriedl_XT || jfriedl_XR)
1621f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
1622f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#     include <sys/time.h>
1623f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#     include <time.h>
1624f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      struct timeval start_time, end_time;
1625f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      struct timezone dummy;
1626f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      int i;
1627f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1628f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (jfriedl_XT)
1629f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1630f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          unsigned long newlen = length * jfriedl_XT + strlen(jfriedl_prefix) + strlen(jfriedl_postfix);
1631f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          const char *orig = ptr;
1632f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          ptr = malloc(newlen + 1);
1633f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (!ptr) {
1634f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                  printf("out of memory");
1635f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                  pcregrep_exit(2);
1636f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1637f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          endptr = ptr;
1638f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          strcpy(endptr, jfriedl_prefix); endptr += strlen(jfriedl_prefix);
1639f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          for (i = 0; i < jfriedl_XT; i++) {
1640f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                  strncpy(endptr, orig,  length);
1641f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                  endptr += length;
1642f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1643f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          strcpy(endptr, jfriedl_postfix); endptr += strlen(jfriedl_postfix);
1644f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          length = newlen;
1645f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1646f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1647f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (gettimeofday(&start_time, &dummy) != 0)
1648f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              perror("bad gettimeofday");
1649f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1650f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1651f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      for (i = 0; i < jfriedl_XR; i++)
1652f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          match = (pcre_exec(patterns->compiled, patterns->hint, ptr, length, 0,
1653f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              PCRE_NOTEMPTY, offsets, OFFSET_SIZE) >= 0);
1654f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1655f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (gettimeofday(&end_time, &dummy) != 0)
1656f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              perror("bad gettimeofday");
1657f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1658f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      double delta = ((end_time.tv_sec + (end_time.tv_usec / 1000000.0))
1659f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                      -
1660f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                      (start_time.tv_sec + (start_time.tv_usec / 1000000.0)));
1661f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1662f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      printf("%s TIMER[%.4f]\n", match ? "MATCH" : "FAIL", delta);
1663f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return 0;
1664f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
1665f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1666f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1667f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* We come back here after a match when show_only_matching is set, in order
1668f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  to find any further matches in the same line. This applies to
1669f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  --only-matching, --file-offsets, and --line-offsets. */
1670f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1671f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ONLY_MATCHING_RESTART:
1672f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1673f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Run through all the patterns until one matches or there is an error other
1674f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  than NOMATCH. This code is in a subroutine so that it can be re-used for
1675f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  finding subsequent matches when colouring matched lines. After finding one
1676f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  match, set PCRE_NOTEMPTY to disable any further matches of null strings in
1677f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  this line. */
1678f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1679f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  match = match_patterns(matchptr, length, options, startoffset, offsets, &mrc);
1680f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  options = PCRE_NOTEMPTY;
1681f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1682f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If it's a match or a not-match (as required), do what's wanted. */
1683f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1684f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (match != invert)
1685f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1686f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    BOOL hyphenprinted = FALSE;
1687f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1688f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* We've failed if we want a file that doesn't have any matches. */
1689f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1690f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (filenames == FN_NOMATCH_ONLY) return 1;
1691f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1692f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Just count if just counting is wanted. */
1693f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1694f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (count_only) count++;
1695f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1696f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* When handling a binary file and binary-files==binary, the "binary"
1697f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    variable will be set true (it's false in all other cases). In this
1698f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    situation we just want to output the file name. No need to scan further. */
1699f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1700f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (binary)
1701f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1702f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stdout, "Binary file %s matches\n", filename);
1703f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return 0;
1704f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1705f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1706f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* If all we want is a file name, there is no need to scan any more lines
1707f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    in the file. */
1708f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1709f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (filenames == FN_MATCH_ONLY)
1710f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1711f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stdout, "%s\n", printname);
1712f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return 0;
1713f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1714f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1715f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Likewise, if all we want is a yes/no answer. */
1716f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1717f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (quiet) return 0;
1718f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1719f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* The --only-matching option prints just the substring that matched,
1720f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    and/or one or more captured portions of it, as long as these strings are
1721f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    not empty. The --file-offsets and --line-offsets options output offsets for
1722f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    the matching substring (all three set show_only_matching). None of these
1723f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    mutually exclusive options prints any context. Afterwards, adjust the start
1724f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    and then jump back to look for further matches in the same line. If we are
1725f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    in invert mode, however, nothing is printed and we do not restart - this
1726f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    could still be useful because the return code is set. */
1727f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1728f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (show_only_matching)
1729f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1730f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (!invert)
1731f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1732f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (printname != NULL) fprintf(stdout, "%s:", printname);
1733f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (number) fprintf(stdout, "%d:", linenumber);
1734f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1735f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* Handle --line-offsets */
1736f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1737f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (line_offsets)
1738f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr),
1739f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            offsets[1] - offsets[0]);
1740f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1741f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* Handle --file-offsets */
1742f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1743f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        else if (file_offsets)
1744f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          fprintf(stdout, "%d,%d\n",
1745f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            (int)(filepos + matchptr + offsets[0] - ptr),
1746f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            offsets[1] - offsets[0]);
1747f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1748f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* Handle --only-matching, which may occur many times */
1749f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1750f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        else
1751f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1752f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          BOOL printed = FALSE;
1753f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          omstr *om;
1754f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1755f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          for (om = only_matching; om != NULL; om = om->next)
1756f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            {
1757f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            int n = om->groupnum;
1758f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            if (n < mrc)
1759f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              {
1760f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              int plen = offsets[2*n + 1] - offsets[2*n];
1761f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              if (plen > 0)
1762f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                {
1763f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                if (printed) fprintf(stdout, "%s", om_separator);
1764f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1765f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                FWRITE(matchptr + offsets[n*2], 1, plen, stdout);
1766f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
1767f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                printed = TRUE;
1768f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                }
1769f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              }
1770f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            }
1771f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1772f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (printed || printname != NULL || number) fprintf(stdout, "\n");
1773f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1774f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1775f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* Prepare to repeat to find the next match */
1776f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1777f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        match = FALSE;
1778f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (line_buffered) fflush(stdout);
1779f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        rc = 0;                      /* Had some success */
1780f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        startoffset = offsets[1];    /* Restart after the match */
1781f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        goto ONLY_MATCHING_RESTART;
1782f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1783f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1784f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1785f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* This is the default case when none of the above options is set. We print
1786f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    the matching lines(s), possibly preceded and/or followed by other lines of
1787f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    context. */
1788f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1789f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
1790f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1791f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* See if there is a requirement to print some "after" lines from a
1792f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      previous match. We never print any overlaps. */
1793f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1794f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (after_context > 0 && lastmatchnumber > 0)
1795f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1796f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int ellength;
1797f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int linecount = 0;
1798f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        char *p = lastmatchrestart;
1799f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1800f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        while (p < ptr && linecount < after_context)
1801f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1802f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          p = end_of_line(p, ptr, &ellength);
1803f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          linecount++;
1804f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1805f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1806f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* It is important to advance lastmatchrestart during this printing so
1807f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        that it interacts correctly with any "before" printing below. Print
1808f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        each line's data using fwrite() in case there are binary zeroes. */
1809f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1810f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        while (lastmatchrestart < p)
1811f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1812f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          char *pp = lastmatchrestart;
1813f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (printname != NULL) fprintf(stdout, "%s-", printname);
1814f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (number) fprintf(stdout, "%d-", lastmatchnumber++);
1815f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          pp = end_of_line(pp, endptr, &ellength);
1816f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
1817f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          lastmatchrestart = pp;
1818f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1819f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (lastmatchrestart != ptr) hyphenpending = TRUE;
1820f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1821f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1822f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* If there were non-contiguous lines printed above, insert hyphens. */
1823f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1824f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (hyphenpending)
1825f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1826f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stdout, "--\n");
1827f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        hyphenpending = FALSE;
1828f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        hyphenprinted = TRUE;
1829f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1830f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1831f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* See if there is a requirement to print some "before" lines for this
1832f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      match. Again, don't print overlaps. */
1833f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1834f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (before_context > 0)
1835f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1836f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int linecount = 0;
1837f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        char *p = ptr;
1838f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1839f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&
1840f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich               linecount < before_context)
1841f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1842f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          linecount++;
1843f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          p = previous_line(p, main_buffer);
1844f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1845f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1846f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
1847f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          fprintf(stdout, "--\n");
1848f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1849f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        while (p < ptr)
1850f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1851f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          int ellength;
1852f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          char *pp = p;
1853f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (printname != NULL) fprintf(stdout, "%s-", printname);
1854f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (number) fprintf(stdout, "%d-", linenumber - linecount--);
1855f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          pp = end_of_line(pp, endptr, &ellength);
1856f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          FWRITE(p, 1, pp - p, stdout);
1857f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          p = pp;
1858f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1859f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1860f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1861f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Now print the matching line(s); ensure we set hyphenpending at the end
1862f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      of the file if any context lines are being output. */
1863f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1864f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (after_context > 0 || before_context > 0)
1865f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        endhyphenpending = TRUE;
1866f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1867f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (printname != NULL) fprintf(stdout, "%s:", printname);
1868f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (number) fprintf(stdout, "%d:", linenumber);
1869f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1870f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* In multiline mode, we want to print to the end of the line in which
1871f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      the end of the matched string is found, so we adjust linelength and the
1872f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      line number appropriately, but only when there actually was a match
1873f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      (invert not set). Because the PCRE_FIRSTLINE option is set, the start of
1874f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      the match will always be before the first newline sequence. */
1875f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1876f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (multiline & !invert)
1877f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1878f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        char *endmatch = ptr + offsets[1];
1879f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        t = ptr;
1880f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        while (t <= endmatch)
1881f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1882f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          t = end_of_line(t, endptr, &endlinelength);
1883f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (t < endmatch) linenumber++; else break;
1884f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1885f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        linelength = t - ptr - endlinelength;
1886f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1887f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1888f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /*** NOTE: Use only fwrite() to output the data line, so that binary
1889f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      zeroes are treated as just another data character. */
1890f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1891f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* This extra option, for Jeffrey Friedl's debugging requirements,
1892f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      replaces the matched string, or a specific captured string if it exists,
1893f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      with X. When this happens, colouring is ignored. */
1894f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1895f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
1896f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (S_arg >= 0 && S_arg < mrc)
1897f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1898f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int first = S_arg * 2;
1899f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int last  = first + 1;
1900f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        FWRITE(ptr, 1, offsets[first], stdout);
1901f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stdout, "X");
1902f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        FWRITE(ptr + offsets[last], 1, linelength - offsets[last], stdout);
1903f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1904f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else
1905f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
1906f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1907f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* We have to split the line(s) up if colouring, and search for further
1908f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      matches, but not of course if the line is a non-match. */
1909f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1910f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (do_colour && !invert)
1911f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
1912f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int plength;
1913f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        FWRITE(ptr, 1, offsets[0], stdout);
1914f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1915f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1916f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stdout, "%c[00m", 0x1b);
1917f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        for (;;)
1918f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
1919f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          startoffset = offsets[1];
1920f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (startoffset >= (int)linelength + endlinelength ||
1921f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              !match_patterns(matchptr, length, options, startoffset, offsets,
1922f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                &mrc))
1923f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            break;
1924f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
1925f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
1926f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
1927f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          fprintf(stdout, "%c[00m", 0x1b);
1928f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
1929f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1930f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        /* In multiline mode, we may have already printed the complete line
1931f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        and its line-ending characters (if they matched the pattern), so there
1932f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        may be no more to print. */
1933f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1934f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        plength = (int)((linelength + endlinelength) - startoffset);
1935f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout);
1936f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
1937f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1938f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Not colouring; no need to search for further matches */
1939f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1940f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else FWRITE(ptr, 1, linelength + endlinelength, stdout);
1941f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1942f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1943f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* End of doing what has to be done for a match. If --line-buffered was
1944f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    given, flush the output. */
1945f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1946f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (line_buffered) fflush(stdout);
1947f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    rc = 0;    /* Had some success */
1948f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1949f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Remember where the last match happened for after_context. We remember
1950f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    where we are about to restart, and that line's number. */
1951f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1952f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    lastmatchrestart = ptr + linelength + endlinelength;
1953f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    lastmatchnumber = linenumber + 1;
1954f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1955f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1956f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* For a match in multiline inverted mode (which of course did not cause
1957f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  anything to be printed), we have to move on to the end of the match before
1958f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  proceeding. */
1959f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1960f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (multiline && invert && match)
1961f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1962f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int ellength;
1963f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *endmatch = ptr + offsets[1];
1964f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    t = ptr;
1965f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while (t < endmatch)
1966f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
1967f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      t = end_of_line(t, endptr, &ellength);
1968f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (t <= endmatch) linenumber++; else break;
1969f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
1970f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    endmatch = end_of_line(endmatch, endptr, &ellength);
1971f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    linelength = endmatch - ptr - ellength;
1972f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1973f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1974f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Advance to after the newline and increment the line number. The file
1975f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  offset to the current line is maintained in filepos. */
1976f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1977f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ptr += linelength + endlinelength;
1978f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  filepos += (int)(linelength + endlinelength);
1979f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  linenumber++;
1980f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1981f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If input is line buffered, and the buffer is not yet full, read another
1982f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  line and add it into the buffer. */
1983f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1984f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (input_line_buffered && bufflength < (size_t)bufsize)
1985f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1986f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in);
1987f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    bufflength += add;
1988f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    endptr += add;
1989f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
1990f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1991f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If we haven't yet reached the end of the file (the buffer is full), and
1992f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  the current point is in the top 1/3 of the buffer, slide the buffer down by
1993f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  1/3 and refill it. Before we do this, if some unprinted "after" lines are
1994f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  about to be lost, print them. */
1995f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
1996f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird)
1997f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
1998f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (after_context > 0 &&
1999f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        lastmatchnumber > 0 &&
2000f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        lastmatchrestart < main_buffer + bufthird)
2001f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2002f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
2003f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      lastmatchnumber = 0;
2004f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2005f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2006f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Now do the shuffle */
2007f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2008f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
2009f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    ptr -= bufthird;
2010f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2011f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
2012f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (frtype == FR_LIBZ)
2013f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      bufflength = 2*bufthird +
2014f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        gzread (ingz, main_buffer + 2*bufthird, bufthird);
2015f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
2016f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2017f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2018f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
2019f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (frtype == FR_LIBBZ2)
2020f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      bufflength = 2*bufthird +
2021f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird);
2022f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
2023f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2024f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2025f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    bufflength = 2*bufthird +
2026f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      (input_line_buffered?
2027f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       read_one_line(main_buffer + 2*bufthird, bufthird, in) :
2028f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       fread(main_buffer + 2*bufthird, 1, bufthird, in));
2029f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    endptr = main_buffer + bufflength;
2030f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2031f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Adjust any last match point */
2032f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2033f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (lastmatchnumber > 0) lastmatchrestart -= bufthird;
2034f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2035f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }     /* Loop through the whole file */
2036f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2037f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* End of file; print final "after" lines if wanted; do_after_lines sets
2038f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichhyphenpending if it prints something. */
2039f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2040f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (!show_only_matching && !count_only)
2041f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2042f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
2043f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  hyphenpending |= endhyphenpending;
2044f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2045f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2046f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Print the file name if we are looking for those without matches and there
2047f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwere none. If we found a match, we won't have got this far. */
2048f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2049f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (filenames == FN_NOMATCH_ONLY)
2050f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2051f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stdout, "%s\n", printname);
2052f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 0;
2053f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2054f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2055f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Print the match count if wanted */
2056f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2057f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (count_only)
2058f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2059f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (count > 0 || !omit_zero_count)
2060f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2061f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (printname != NULL && filenames != FN_NONE)
2062f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stdout, "%s:", printname);
2063f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stdout, "%d\n", count);
2064f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2065f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2066f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2067f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn rc;
2068f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2069f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2070f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2071f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2072f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2073f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*     Grep a file or recurse into a directory    *
2074f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2075f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2076f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Given a path name, if it's a directory, scan all the files if we are
2077f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrecursing; if it's a file, grep it.
2078f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2079f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
2080f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pathname          the path to investigate
2081f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  dir_recurse       TRUE if recursing is wanted (-r or -drecurse)
2082f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  only_one_at_top   TRUE if the path is the only one at toplevel
2083f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2084f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:  -1 the file/directory was skipped
2085f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           0 if there was at least one match
2086f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           1 if there were no matches
2087f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           2 there was some kind of error
2088f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2089f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichHowever, file opening failures are suppressed if "silent" is set.
2090f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
2091f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2092f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
2093f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichgrep_or_recurse(char *pathname, BOOL dir_recurse, BOOL only_one_at_top)
2094f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2095f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint rc = 1;
2096f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint frtype;
2097f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichvoid *handle;
2098f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *lastcomp;
2099f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichFILE *in = NULL;           /* Ensure initialized */
2100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
2102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichgzFile ingz = NULL;
2103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
2106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBZFILE *inbz2 = NULL;
2107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
2110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint pathlen;
2111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
2114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint zos_type;
2115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichFILE *zos_test_file;
2116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If the file name is "-" we scan stdin */
2119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (strcmp(pathname, "-") == 0)
2121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return pcregrep(stdin, FR_PLAIN, stdin_name,
2123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?
2124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      stdin_name : NULL);
2125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Inclusion and exclusion: --include-dir and --exclude-dir apply only to
2128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichdirectories, whereas --include and --exclude apply to everything else. The test
2129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichis against the final component of the path. */
2130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichlastcomp = strrchr(pathname, FILESEP);
2132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichlastcomp = (lastcomp == NULL)? pathname : lastcomp + 1;
2133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If the file is a directory, skip if not recursing or if explicitly excluded.
2135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichOtherwise, scan the directory and recurse for each path within it. The scanning
2136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichcode is localized so it can be made system-specific. */
2137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* For z/OS, determine the file type. */
2140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
2142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichzos_test_file =  fopen(pathname,"rb");
2143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (zos_test_file == NULL)
2145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   {
2146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   if (!silent) fprintf(stderr, "pcregrep: failed to test next file %s\n",
2147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich     pathname, strerror(errno));
2148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   return -1;
2149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   }
2150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichzos_type = identifyzosfiletype (zos_test_file);
2151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfclose (zos_test_file);
2152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Handle a PDS in separate code */
2154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (zos_type == __ZOS_PDS || zos_type == __ZOS_PDSE)
2156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   {
2157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   return travelonpdsdir (pathname, only_one_at_top);
2158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   }
2159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Deal with regular files in the normal way below. These types are:
2161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   zos_type == __ZOS_PDS_MEMBER
2162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   zos_type == __ZOS_PS
2163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   zos_type == __ZOS_VSAM_KSDS
2164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   zos_type == __ZOS_VSAM_ESDS
2165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich   zos_type == __ZOS_VSAM_RRDS
2166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
2167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Handle a z/OS directory using common code. */
2169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (zos_type == __ZOS_HFS)
2171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich {
2172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif  /* NATIVE_ZOS */
2173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Handle directories: common code for all OS */
2176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (isdirectory(pathname))
2178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (dee_action == dee_SKIP ||
2180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      !test_incexc(lastcomp, include_dir_patterns, exclude_dir_patterns))
2181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return -1;
2182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (dee_action == dee_RECURSE)
2184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char buffer[1024];
2186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *nextfile;
2187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    directory_type *dir = opendirectory(pathname);
2188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (dir == NULL)
2190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (!silent)
2192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", pathname,
2193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          strerror(errno));
2194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return 2;
2195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while ((nextfile = readdirectory(dir)) != NULL)
2198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      int frc;
2200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile);
2201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      frc = grep_or_recurse(buffer, dir_recurse, FALSE);
2202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (frc > 1) rc = frc;
2203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       else if (frc == 0 && rc == 1) rc = 0;
2204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    closedirectory(dir);
2207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return rc;
2208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
2212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich }
2213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If the file is not a directory, check for a regular file, and if it is not,
2216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichskip it if that's been requested. Otherwise, check for an explicit inclusion or
2217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichexclusion. */
2218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (
2220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined NATIVE_ZOS
2221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        (zos_type == __ZOS_NOFILE && DEE_action == DEE_SKIP) ||
2222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else  /* all other OS */
2223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        (!isregfile(pathname) && DEE_action == DEE_SKIP) ||
2224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        !test_incexc(lastcomp, include_patterns, exclude_patterns))
2226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return -1;  /* File skipped */
2227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Control reaches here if we have a regular file, or if we have a directory
2229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichand recursion or skipping was not requested, or if we have anything else and
2230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichskipping was not requested. The scan proceeds. If this is the first and only
2231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichargument at top level, we don't show the file name, unless we are only showing
2232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthe file name, or the filename was forced (-H). */
2233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
2235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpathlen = (int)(strlen(pathname));
2236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Open using zlib if it is supported and the file name ends with .gz. */
2239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
2241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (pathlen > 3 && strcmp(pathname + pathlen - 3, ".gz") == 0)
2242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  ingz = gzopen(pathname, "rb");
2244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (ingz == NULL)
2245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (!silent)
2247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
2248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        strerror(errno));
2249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return 2;
2250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  handle = (void *)ingz;
2252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  frtype = FR_LIBZ;
2253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Otherwise open with bz2lib if it is supported and the name ends with .bz2. */
2258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
2260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (pathlen > 4 && strcmp(pathname + pathlen - 4, ".bz2") == 0)
2261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  inbz2 = BZ2_bzopen(pathname, "rb");
2263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  handle = (void *)inbz2;
2264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  frtype = FR_LIBBZ2;
2265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Otherwise use plain fopen(). The label is so that we can come back here if
2270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichan attempt to read a .bz2 file indicates that it really is a plain file. */
2271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
2273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichPLAIN_FILE:
2274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  in = fopen(pathname, "rb");
2277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  handle = (void *)in;
2278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  frtype = FR_PLAIN;
2279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* All the opening methods return errno when they fail. */
2282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (handle == NULL)
2284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!silent)
2286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pathname,
2287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      strerror(errno));
2288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 2;
2289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Now grep the file */
2292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT ||
2294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);
2295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Close in an appropriate manner. */
2297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBZ
2299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (frtype == FR_LIBZ)
2300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  gzclose(ingz);
2301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If it is a .bz2 file and the result is 3, it means that the first attempt to
2305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichread failed. If the error indicates that the file isn't in fact bzipped, try
2306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichagain as a normal file. */
2307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_LIBBZ2
2309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (frtype == FR_LIBBZ2)
2310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (rc == 3)
2312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int errnum;
2314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    const char *err = BZ2_bzerror(inbz2, &errnum);
2315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (errnum == BZ_DATA_ERROR_MAGIC)
2316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      BZ2_bzclose(inbz2);
2318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      goto PLAIN_FILE;
2319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (!silent)
2321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",
2322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        pathname, err);
2323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    rc = 2;    /* The normal "something went wrong" code */
2324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  BZ2_bzclose(inbz2);
2326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Normal file close */
2331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfclose(in);
2333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Pass back the yield from pcregrep(). */
2335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2336f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn rc;
2337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2339f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2341f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*    Handle a single-letter, no data option      *
2343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2344f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic int
2346f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichhandle_option(int letter, int options)
2347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichswitch(letter)
2349f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case N_FOFFSETS: file_offsets = TRUE; break;
2351f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case N_HELP: help(); pcregrep_exit(0);
2352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case N_LBUFFER: line_buffered = TRUE; break;
2353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case N_LOFFSETS: line_offsets = number = TRUE; break;
2354f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break;
2355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'a': binary_files = BIN_TEXT; break;
2356f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'c': count_only = TRUE; break;
2357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'F': process_options |= PO_FIXED_STRINGS; break;
2358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'H': filenames = FN_FORCE; break;
2359f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'I': binary_files = BIN_NOMATCH; break;
2360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'h': filenames = FN_NONE; break;
2361f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'i': options |= PCRE_CASELESS; break;
2362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
2363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'L': filenames = FN_NOMATCH_ONLY; break;
2364f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break;
2365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'n': number = TRUE; break;
2366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'o':
2368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  only_matching_last = add_number(0, only_matching_last);
2369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (only_matching == NULL) only_matching = only_matching_last;
2370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  break;
2371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'q': quiet = TRUE; break;
2373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'r': dee_action = dee_RECURSE; break;
2374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 's': silent = TRUE; break;
2375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'u': options |= PCRE_UTF8; utf8 = TRUE; break;
2376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'v': invert = TRUE; break;
2377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'w': process_options |= PO_WORD_MATCH; break;
2378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'x': process_options |= PO_LINE_MATCH; break;
2379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 'V':
2381f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stdout, "pcregrep version %s\n", pcre_version());
2382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(0);
2383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  break;
2384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  default:
2386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Unknown option -%c\n", letter);
2387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(usage(2));
2388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn options;
2391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2396f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*          Construct printed ordinal             *
2398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This turns a number into "1st", "3rd", etc. */
2401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char *
2403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichordin(int n)
2404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic char buffer[8];
2406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *p = buffer;
2407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichsprintf(p, "%d", n);
2408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (*p != 0) p++;
2409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichswitch (n%10)
2410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 1: strcpy(p, "st"); break;
2412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 2: strcpy(p, "nd"); break;
2413f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 3: strcpy(p, "rd"); break;
2414f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  default: strcpy(p, "th"); break;
2415f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2416f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn buffer;
2417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*          Compile a single pattern              *
2423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Do nothing if the pattern has already been compiled. This is the case for
2426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichinclude/exclude patterns read from a file.
2427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichWhen the -F option has been used, each "pattern" may be a list of strings,
2429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichseparated by line breaks. They will be matched literally. We split such a
2430f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstring and compile the first substring, inserting an additional block into the
2431f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpattern chain.
2432f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2433f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
2434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  p              points to the pattern block
2435f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  options        the PCRE options
2436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  popts          the processing options
2437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fromfile       TRUE if the pattern was read from a file
2438f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fromtext       file name or identifying text (e.g. "include")
2439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  count          0 if this is the only command line pattern, or
2440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                 number of the command line pattern, or
2441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich                 linenumber for a pattern from a file
2442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:         TRUE on success, FALSE after an error
2444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
2445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
2447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichcompile_pattern(patstr *p, int options, int popts, int fromfile,
2448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  const char *fromtext, int count)
2449f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar buffer[PATBUFSIZE];
2451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst char *error;
2452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *ps = p->string;
2453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint patlen = strlen(ps);
2454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint errptr;
2455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (p->compiled != NULL) return TRUE;
2457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif ((popts & PO_FIXED_STRINGS) != 0)
2459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int ellength;
2461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *eop = ps + patlen;
2462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *pe = end_of_line(ps, eop, &ellength);
2463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (ellength != 0)
2465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (add_pattern(pe, p) == NULL) return FALSE;
2467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    patlen = (int)(pe - ps - ellength);
2468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2470f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2471f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichsprintf(buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]);
2472f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichp->compiled = pcre_compile(buffer, options, &error, &errptr, pcretables);
2473f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (p->compiled != NULL) return TRUE;
2474f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2475f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Handle compile errors */
2476f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2477f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevicherrptr -= (int)strlen(prefix[popts]);
2478f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (errptr > patlen) errptr = patlen;
2479f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2480f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (fromfile)
2481f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2482f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Error in regex in line %d of %s "
2483f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    "at offset %d: %s\n", count, fromtext, errptr, error);
2484f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2485f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2486f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2487f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (count == 0)
2488f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Error in %s regex at offset %d: %s\n",
2489f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fromtext, errptr, error);
2490f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
2491f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Error in %s %s regex at offset %d: %s\n",
2492f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      ordin(count), fromtext, errptr, error);
2493f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2494f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2495f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn FALSE;
2496f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2497f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2498f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2499f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2500f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2501f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*     Read and compile a file of patterns        *
2502f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2503f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2504f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* This is used for --filelist, --include-from, and --exclude-from.
2505f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2506f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichArguments:
2507f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  name         the name of the file; "-" is stdin
2508f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patptr       pointer to the pattern chain anchor
2509f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patlastptr   pointer to the last pattern pointer
2510f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  popts        the process options to pass to pattern_compile()
2511f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2512f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichReturns:       TRUE if all went well
2513f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*/
2514f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2515f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic BOOL
2516f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichread_pattern_file(char *name, patstr **patptr, patstr **patlastptr, int popts)
2517f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2518f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint linenumber = 0;
2519f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichFILE *f;
2520f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar *filename;
2521f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchar buffer[PATBUFSIZE];
2522f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2523f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (strcmp(name, "-") == 0)
2524f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2525f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  f = stdin;
2526f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  filename = stdin_name;
2527f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2528f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
2529f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2530f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  f = fopen(name, "r");
2531f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (f == NULL)
2532f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2533f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Failed to open %s: %s\n", name, strerror(errno));
2534f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return FALSE;
2535f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2536f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  filename = name;
2537f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2538f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2539f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (fgets(buffer, PATBUFSIZE, f) != NULL)
2540f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2541f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *s = buffer + (int)strlen(buffer);
2542f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
2543f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *s = 0;
2544f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  linenumber++;
2545f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (buffer[0] == 0) continue;   /* Skip blank lines */
2546f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2547f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Note: this call to add_pattern() puts a pointer to the local variable
2548f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  "buffer" into the pattern chain. However, that pointer is used only when
2549f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  compiling the pattern, which happens immediately below, so we flatten it
2550f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  afterwards, as a precaution against any later code trying to use it. */
2551f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2552f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  *patlastptr = add_pattern(buffer, *patlastptr);
2553f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*patlastptr == NULL)
2554f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2555f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (f != stdin) fclose(f);
2556f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    return FALSE;
2557f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2558f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*patptr == NULL) *patptr = *patlastptr;
2559f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2560f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* This loop is needed because compiling a "pattern" when -F is set may add
2561f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  on additional literal patterns if the original contains a newline. In the
2562f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  common case, it never will, because fgets() stops at a newline. However,
2563f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  the -N option can be used to give pcregrep a different newline setting. */
2564f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2565f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  for(;;)
2566f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2567f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (!compile_pattern(*patlastptr, pcre_options, popts, TRUE, filename,
2568f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        linenumber))
2569f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2570f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (f != stdin) fclose(f);
2571f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      return FALSE;
2572f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2573f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    (*patlastptr)->string = NULL;            /* Insurance */
2574f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if ((*patlastptr)->next == NULL) break;
2575f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *patlastptr = (*patlastptr)->next;
2576f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2577f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2578f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2579f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (f != stdin) fclose(f);
2580f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturn TRUE;
2581f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
2582f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2583f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2584f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2585f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/*************************************************
2586f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*                Main program                    *
2587f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich*************************************************/
2588f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2589f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Returns 0 if something matched, 1 if nothing matched, 2 after an error. */
2590f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2591f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint
2592f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmain(int argc, char **argv)
2593f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{
2594f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint i, j;
2595f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichint rc = 1;
2596f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichBOOL only_one_at_top;
2597f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpatstr *cp;
2598f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfnstr *fn;
2599f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst char *locale_from = "--locale";
2600f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichconst char *error;
2601f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2602f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
2603f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcre_jit_stack *jit_stack = NULL;
2604f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2605f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2606f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Set the default line ending value from the default in the PCRE library;
2607f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich"lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
2608f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichNote that the return values from pcre_config(), though derived from the ASCII
2609f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichcodes, are the same in EBCDIC environments, so we must use the actual values
2610f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrather than escapes such as as '\r'. */
2611f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2612f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich(void)pcre_config(PCRE_CONFIG_NEWLINE, &i);
2613f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichswitch(i)
2614f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2615f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  default:               newline = (char *)"lf"; break;
2616f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case 13:               newline = (char *)"cr"; break;
2617f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case (13 << 8) | 10:   newline = (char *)"crlf"; break;
2618f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case -1:               newline = (char *)"any"; break;
2619f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  case -2:               newline = (char *)"anycrlf"; break;
2620f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2621f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2622f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Process the options */
2623f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2624f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (i = 1; i < argc; i++)
2625f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2626f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  option_item *op = NULL;
2627f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char *option_data = (char *)"";    /* default to keep compiler happy */
2628f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  BOOL longop;
2629f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  BOOL longopwasequals = FALSE;
2630f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2631f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (argv[i][0] != '-') break;
2632f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2633f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If we hit an argument that is just "-", it may be a reference to STDIN,
2634f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  but only if we have previously had -e or -f to define the patterns. */
2635f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2636f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (argv[i][1] == 0)
2637f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2638f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (pattern_files != NULL || patterns != NULL) break;
2639f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else pcregrep_exit(usage(2));
2640f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2641f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2642f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Handle a long name option, or -- to terminate the options */
2643f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2644f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (argv[i][1] == '-')
2645f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2646f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *arg = argv[i] + 2;
2647f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *argequals = strchr(arg, '=');
2648f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2649f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*arg == 0)    /* -- terminates options */
2650f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2651f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      i++;
2652f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;                /* out of the options-handling loop */
2653f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2654f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2655f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    longop = TRUE;
2656f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2657f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    /* Some long options have data that follows after =, for example file=name.
2658f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    Some options have variations in the long name spelling: specifically, we
2659f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    allow "regexp" because GNU grep allows it, though I personally go along
2660f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    with Jeffrey Friedl and Larry Wall in preferring "regex" without the "p".
2661f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    These options are entered in the table as "regex(p)". Options can be in
2662f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    both these categories. */
2663f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2664f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    for (op = optionlist; op->one_char != 0; op++)
2665f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2666f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      char *opbra = strchr(op->long_name, '(');
2667f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      char *equals = strchr(op->long_name, '=');
2668f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2669f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Handle options with only one spelling of the name */
2670f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2671f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (opbra == NULL)     /* Does not contain '(' */
2672f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2673f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (equals == NULL)  /* Not thing=data case */
2674f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
2675f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (strcmp(arg, op->long_name) == 0) break;
2676f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
2677f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        else                 /* Special case xxx=data */
2678f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
2679f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          int oplen = (int)(equals - op->long_name);
2680f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          int arglen = (argequals == NULL)?
2681f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            (int)strlen(arg) : (int)(argequals - arg);
2682f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (oplen == arglen && strncmp(arg, op->long_name, oplen) == 0)
2683f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            {
2684f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            option_data = arg + arglen;
2685f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            if (*option_data == '=')
2686f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              {
2687f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              option_data++;
2688f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              longopwasequals = TRUE;
2689f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              }
2690f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            break;
2691f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            }
2692f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
2693f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2694f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2695f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Handle options with an alternate spelling of the name */
2696f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2697f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else
2698f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2699f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        char buff1[24];
2700f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        char buff2[24];
2701f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2702f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int baselen = (int)(opbra - op->long_name);
2703f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int fulllen = (int)(strchr(op->long_name, ')') - op->long_name + 1);
2704f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        int arglen = (argequals == NULL || equals == NULL)?
2705f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          (int)strlen(arg) : (int)(argequals - arg);
2706f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2707f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        sprintf(buff1, "%.*s", baselen, op->long_name);
2708f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
2709f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2710f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (strncmp(arg, buff1, arglen) == 0 ||
2711f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           strncmp(arg, buff2, arglen) == 0)
2712f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          {
2713f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          if (equals != NULL && argequals != NULL)
2714f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            {
2715f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            option_data = argequals;
2716f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            if (*option_data == '=')
2717f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              {
2718f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              option_data++;
2719f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              longopwasequals = TRUE;
2720f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich              }
2721f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich            }
2722f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          break;
2723f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          }
2724f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2725f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2726f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2727f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (op->one_char == 0)
2728f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2729f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]);
2730f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      pcregrep_exit(usage(2));
2731f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2732f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2733f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2734f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Jeffrey Friedl's debugging harness uses these additional options which
2735f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  are not in the right form for putting in the option table because they use
2736f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  only one hyphen, yet are more than one character long. By putting them
2737f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  separately here, they will not get displayed as part of the help() output,
2738f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  but I don't think Jeffrey will care about that. */
2739f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2740f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
2741f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (strcmp(argv[i], "-pre") == 0) {
2742f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          jfriedl_prefix = argv[++i];
2743f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          continue;
2744f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  } else if (strcmp(argv[i], "-post") == 0) {
2745f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          jfriedl_postfix = argv[++i];
2746f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          continue;
2747f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  } else if (strcmp(argv[i], "-XT") == 0) {
2748f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          sscanf(argv[++i], "%d", &jfriedl_XT);
2749f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          continue;
2750f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  } else if (strcmp(argv[i], "-XR") == 0) {
2751f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          sscanf(argv[++i], "%d", &jfriedl_XR);
2752f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          continue;
2753f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2754f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2755f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2756f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2757f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* One-char options; many that have no data may be in a single argument; we
2758f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  continue till we hit the last one or one that needs data. */
2759f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2760f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
2761f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2762f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *s = argv[i] + 1;
2763f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    longop = FALSE;
2764f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2765f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while (*s != 0)
2766f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2767f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      for (op = optionlist; op->one_char != 0; op++)
2768f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2769f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (*s == op->one_char) break;
2770f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2771f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (op->one_char == 0)
2772f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2773f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n",
2774f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich          *s, argv[i]);
2775f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        pcregrep_exit(usage(2));
2776f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2777f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2778f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      option_data = s+1;
2779f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2780f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Break out if this is the last character in the string; it's handled
2781f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      below like a single multi-char option. */
2782f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2783f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (*option_data == 0) break;
2784f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2785f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Check for a single-character option that has data: OP_OP_NUMBER(S)
2786f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      are used for ones that either have a numerical number or defaults, i.e.
2787f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      the data is optional. If a digit follows, there is data; if not, carry on
2788f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      with other single-character options in the same string. */
2789f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2790f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (op->type == OP_OP_NUMBER || op->type == OP_OP_NUMBERS)
2791f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2792f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (isdigit((unsigned char)s[1])) break;
2793f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2794f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else   /* Check for an option with data */
2795f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        {
2796f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        if (op->type != OP_NODATA) break;
2797f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        }
2798f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2799f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      /* Handle a single-character option with no data, then loop for the
2800f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      next character in the string. */
2801f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2802f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      pcre_options = handle_option(*s++, pcre_options);
2803f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2804f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2805f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2806f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* At this point we should have op pointing to a matched option. If the type
2807f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  is NO_DATA, it means that there is no data, and the option might set
2808f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  something in the PCRE options. */
2809f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2810f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (op->type == OP_NODATA)
2811f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2812f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    pcre_options = handle_option(op->one_char, pcre_options);
2813f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    continue;
2814f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2815f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2816f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If the option type is OP_OP_STRING or OP_OP_NUMBER(S), it's an option that
2817f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  either has a value or defaults to something. It cannot have data in a
2818f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  separate item. At the moment, the only such options are "colo(u)r",
2819f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  "only-matching", and Jeffrey Friedl's special -S debugging option. */
2820f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2821f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*option_data == 0 &&
2822f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      (op->type == OP_OP_STRING || op->type == OP_OP_NUMBER ||
2823f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       op->type == OP_OP_NUMBERS))
2824f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2825f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    switch (op->one_char)
2826f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2827f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case N_COLOUR:
2828f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      colour_option = (char *)"auto";
2829f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
2830f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2831f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 'o':
2832f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      only_matching_last = add_number(0, only_matching_last);
2833f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (only_matching == NULL) only_matching = only_matching_last;
2834f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
2835f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2836f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
2837f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      case 'S':
2838f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      S_arg = 0;
2839f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      break;
2840f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
2841f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2842f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    continue;
2843f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2844f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2845f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Otherwise, find the data string for the option. */
2846f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2847f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (*option_data == 0)
2848f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2849f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (i >= argc - 1 || longopwasequals)
2850f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2851f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: Data missing after %s\n", argv[i]);
2852f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      pcregrep_exit(usage(2));
2853f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2854f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    option_data = argv[++i];
2855f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2856f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2857f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If the option type is OP_OP_NUMBERS, the value is a number that is to be
2858f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  added to a chain of numbers. */
2859f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2860f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (op->type == OP_OP_NUMBERS)
2861f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2862f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    unsigned long int n = decode_number(option_data, op, longop);
2863f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    omdatastr *omd = (omdatastr *)op->dataptr;
2864f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *(omd->lastptr) = add_number((int)n, *(omd->lastptr));
2865f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*(omd->anchor) == NULL) *(omd->anchor) = *(omd->lastptr);
2866f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2867f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2868f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If the option type is OP_PATLIST, it's the -e option, or one of the
2869f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  include/exclude options, which can be called multiple times to create lists
2870f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  of patterns. */
2871f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2872f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (op->type == OP_PATLIST)
2873f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2874f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    patdatastr *pd = (patdatastr *)op->dataptr;
2875f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *(pd->lastptr) = add_pattern(option_data, *(pd->lastptr));
2876f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*(pd->lastptr) == NULL) goto EXIT2;
2877f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*(pd->anchor) == NULL) *(pd->anchor) = *(pd->lastptr);
2878f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2879f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2880f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* If the option type is OP_FILELIST, it's one of the options that names a
2881f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  file. */
2882f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2883f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (op->type == OP_FILELIST)
2884f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2885f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fndatastr *fd = (fndatastr *)op->dataptr;
2886f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fn = (fnstr *)malloc(sizeof(fnstr));
2887f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (fn == NULL)
2888f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2889f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: malloc failed\n");
2890f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      goto EXIT2;
2891f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2892f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fn->next = NULL;
2893f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fn->name = option_data;
2894f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*(fd->anchor) == NULL)
2895f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      *(fd->anchor) = fn;
2896f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
2897f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      (*(fd->lastptr))->next = fn;
2898f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *(fd->lastptr) = fn;
2899f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2900f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2901f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Handle OP_BINARY_FILES */
2902f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2903f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (op->type == OP_BINFILES)
2904f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2905f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (strcmp(option_data, "binary") == 0)
2906f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      binary_files = BIN_BINARY;
2907f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (strcmp(option_data, "without-match") == 0)
2908f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      binary_files = BIN_NOMATCH;
2909f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (strcmp(option_data, "text") == 0)
2910f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      binary_files = BIN_TEXT;
2911f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else
2912f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
2913f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: unknown value \"%s\" for binary-files\n",
2914f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        option_data);
2915f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      pcregrep_exit(usage(2));
2916f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
2917f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2918f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2919f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  /* Otherwise, deal with a single string or numeric data value. */
2920f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2921f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&
2922f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich           op->type != OP_OP_NUMBER)
2923f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2924f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *((char **)op->dataptr) = option_data;
2925f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2926f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
2927f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2928f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    unsigned long int n = decode_number(option_data, op, longop);
2929f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (op->type == OP_LONGNUMBER) *((unsigned long int *)op->dataptr) = n;
2930f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      else *((int *)op->dataptr) = n;
2931f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2932f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2933f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2934f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Options have been decoded. If -C was used, its value is used as a default
2935f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor -A and -B. */
2936f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2937f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (both_context > 0)
2938f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2939f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (after_context == 0) after_context = both_context;
2940f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (before_context == 0) before_context = both_context;
2941f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2942f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2943f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted.
2944f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichHowever, all three set show_only_matching because they display, each in their
2945f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichown way, only the data that has matched. */
2946f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2947f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif ((only_matching != NULL && (file_offsets || line_offsets)) ||
2948f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    (file_offsets && line_offsets))
2949f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2950f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets "
2951f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    "and/or --line-offsets\n");
2952f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcregrep_exit(usage(2));
2953f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2954f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2955f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (only_matching != NULL || file_offsets || line_offsets)
2956f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  show_only_matching = TRUE;
2957f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2958f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If a locale has not been provided as an option, see if the LC_CTYPE or
2959f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichLC_ALL environment variable is set, and if so, use it. */
2960f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2961f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (locale == NULL)
2962f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2963f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  locale = getenv("LC_ALL");
2964f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  locale_from = "LCC_ALL";
2965f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2966f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2967f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (locale == NULL)
2968f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2969f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  locale = getenv("LC_CTYPE");
2970f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  locale_from = "LC_CTYPE";
2971f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2972f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2973f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If a locale is set, use it to generate the tables the PCRE needs. Otherwise,
2974f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcretables==NULL, which causes the use of default tables. */
2975f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2976f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (locale != NULL)
2977f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2978f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (setlocale(LC_CTYPE, locale) == NULL)
2979f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2980f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Failed to set locale %s (obtained from %s)\n",
2981f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      locale, locale_from);
2982f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
2983f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2984f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcretables = pcre_maketables();
2985f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
2986f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2987f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Sort out colouring */
2988f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
2989f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (colour_option != NULL && strcmp(colour_option, "never") != 0)
2990f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
2991f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(colour_option, "always") == 0) do_colour = TRUE;
2992f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (strcmp(colour_option, "auto") == 0) do_colour = is_stdout_tty();
2993f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
2994f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
2995f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Unknown colour setting \"%s\"\n",
2996f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      colour_option);
2997f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
2998f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
2999f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (do_colour)
3000f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3001f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *cs = getenv("PCREGREP_COLOUR");
3002f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (cs == NULL) cs = getenv("PCREGREP_COLOR");
3003f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (cs != NULL) colour_string = cs;
3004f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3005f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3006f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3007f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Interpret the newline type; the default settings are Unix-like. */
3008f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3009f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (strcmp(newline, "cr") == 0 || strcmp(newline, "CR") == 0)
3010f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3011f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_options |= PCRE_NEWLINE_CR;
3012f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endlinetype = EL_CR;
3013f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3014f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (strcmp(newline, "lf") == 0 || strcmp(newline, "LF") == 0)
3015f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3016f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_options |= PCRE_NEWLINE_LF;
3017f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endlinetype = EL_LF;
3018f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3019f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (strcmp(newline, "crlf") == 0 || strcmp(newline, "CRLF") == 0)
3020f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3021f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_options |= PCRE_NEWLINE_CRLF;
3022f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endlinetype = EL_CRLF;
3023f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3024f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (strcmp(newline, "any") == 0 || strcmp(newline, "ANY") == 0)
3025f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3026f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_options |= PCRE_NEWLINE_ANY;
3027f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endlinetype = EL_ANY;
3028f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3029f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse if (strcmp(newline, "anycrlf") == 0 || strcmp(newline, "ANYCRLF") == 0)
3030f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3031f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  pcre_options |= PCRE_NEWLINE_ANYCRLF;
3032f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  endlinetype = EL_ANYCRLF;
3033f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3034f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichelse
3035f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3036f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: Invalid newline specifier \"%s\"\n", newline);
3037f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  goto EXIT2;
3038f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3039f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3040f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Interpret the text values for -d and -D */
3041f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3042f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (dee_option != NULL)
3043f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3044f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(dee_option, "read") == 0) dee_action = dee_READ;
3045f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (strcmp(dee_option, "recurse") == 0) dee_action = dee_RECURSE;
3046f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (strcmp(dee_option, "skip") == 0) dee_action = dee_SKIP;
3047f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
3048f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3049f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Invalid value \"%s\" for -d\n", dee_option);
3050f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3051f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3052f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3053f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3054f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (DEE_option != NULL)
3055f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3056f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(DEE_option, "read") == 0) DEE_action = DEE_READ;
3057f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else if (strcmp(DEE_option, "skip") == 0) DEE_action = DEE_SKIP;
3058f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  else
3059f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3060f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Invalid value \"%s\" for -D\n", DEE_option);
3061f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3062f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3063f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3064f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3065f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Check the values for Jeffrey Friedl's debugging options. */
3066f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3067f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef JFRIEDL_DEBUG
3068f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (S_arg > 9)
3069f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3070f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: bad value for -S option\n");
3071f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  return 2;
3072f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3073f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (jfriedl_XT != 0 || jfriedl_XR != 0)
3074f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3075f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (jfriedl_XT == 0) jfriedl_XT = 1;
3076f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (jfriedl_XR == 0) jfriedl_XR = 1;
3077f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3078f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
3079f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3080f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Get memory for the main buffer. */
3081f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3082f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichbufsize = 3*bufthird;
3083f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmain_buffer = (char *)malloc(bufsize);
3084f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3085f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (main_buffer == NULL)
3086f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3087f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  fprintf(stderr, "pcregrep: malloc failed\n");
3088f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  goto EXIT2;
3089f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3090f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3091f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If no patterns were provided by -e, and there are no files provided by -f,
3092f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthe first argument is the one and only pattern, and it must exist. */
3093f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3094f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (patterns == NULL && pattern_files == NULL)
3095f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3096f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (i >= argc) return usage(2);
3097f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  patterns = patterns_last = add_pattern(argv[i++], NULL);
3098f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (patterns == NULL) goto EXIT2;
3099f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Compile the patterns that were provided on the command line, either by
3102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichmultiple uses of -e or as a single unkeyed pattern. We cannot do this until
3103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichafter all the command-line options are read so that we know which PCRE options
3104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichto use. When -F is used, compile_pattern() may add another block into the
3105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichchain, so we must not access the next pointer till after the compile. */
3106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next)
3108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!compile_pattern(cp, pcre_options, process_options, FALSE, "command-line",
3110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich       (j == 1 && patterns->next == NULL)? 0 : j))
3111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Read and compile the regular expressions that are provided in files. */
3115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (fn = pattern_files; fn != NULL; fn = fn->next)
3117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!read_pattern_file(fn->name, &patterns, &patterns_last, process_options))
3119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Study the regular expressions, as we will be running them many times. If an
3123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichextra block is needed for a limit, set PCRE_STUDY_EXTRA_NEEDED so that one is
3124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichreturned, even if studying produces no data. */
3125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (match_limit > 0 || match_limit_recursion > 0)
3127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  study_options |= PCRE_STUDY_EXTRA_NEEDED;
3128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Unless JIT has been explicitly disabled, arrange a stack for it to use. */
3130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
3132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
3133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  jit_stack = pcre_jit_stack_alloc(32*1024, 1024*1024);
3134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
3135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (j = 1, cp = patterns; cp != NULL; j++, cp = cp->next)
3137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  cp->hint = pcre_study(cp->compiled, study_options, &error);
3139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (error != NULL)
3140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char s[16];
3142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (patterns->next == NULL) s[0] = 0; else sprintf(s, " number %d", j);
3143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error);
3144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
3147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (jit_stack != NULL && cp->hint != NULL)
3148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    pcre_assign_jit_stack(cp->hint, NULL, jit_stack);
3149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
3150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If --match-limit or --recursion-limit was set, put the value(s) into the
3153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcre_extra block for each pattern. There will always be an extra block because
3154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichof the use of PCRE_STUDY_EXTRA_NEEDED above. */
3155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (cp = patterns; cp != NULL; cp = cp->next)
3157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (match_limit > 0)
3159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT;
3161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    cp->hint->match_limit = match_limit;
3162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (match_limit_recursion > 0)
3165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    cp->hint->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
3167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    cp->hint->match_limit_recursion = match_limit_recursion;
3168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If there are include or exclude patterns read from the command line, compile
3172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthem. -F, -w, and -x do not apply, so the third argument of compile_pattern is
3173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich0. */
3174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (j = 0; j < 4; j++)
3176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int k;
3178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  for (k = 1, cp = *(incexlist[j]); cp != NULL; k++, cp = cp->next)
3179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (!compile_pattern(cp, pcre_options, 0, FALSE, incexname[j],
3181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich         (k == 1 && cp->next == NULL)? 0 : k))
3182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      goto EXIT2;
3183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* Read and compile include/exclude patterns from files. */
3187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (fn = include_from; fn != NULL; fn = fn->next)
3189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!read_pattern_file(fn->name, &include_patterns, &include_patterns_last, 0))
3191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (fn = exclude_from; fn != NULL; fn = fn->next)
3195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (!read_pattern_file(fn->name, &exclude_patterns, &exclude_patterns_last, 0))
3197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    goto EXIT2;
3198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If there are no files that contain lists of files to search, and there are
3201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichno file arguments, search stdin, and then exit. */
3202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (file_lists == NULL && i >= argc)
3204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  rc = pcregrep(stdin, FR_PLAIN, stdin_name,
3206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    (filenames > FN_DEFAULT)? stdin_name : NULL);
3207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  goto EXIT;
3208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* If any files that contains a list of files to search have been specified,
3211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichread them line by line and search the given files. */
3212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (fn = file_lists; fn != NULL; fn = fn->next)
3214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  char buffer[PATBUFSIZE];
3216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  FILE *fl;
3217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (strcmp(fn->name, "-") == 0) fl = stdin; else
3218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    fl = fopen(fn->name, "rb");
3220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (fl == NULL)
3221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
3222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      fprintf(stderr, "pcregrep: Failed to open %s: %s\n", fn->name,
3223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        strerror(errno));
3224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      goto EXIT2;
3225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
3226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  while (fgets(buffer, PATBUFSIZE, fl) != NULL)
3228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    {
3229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    int frc;
3230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    char *end = buffer + (int)strlen(buffer);
3231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    while (end > buffer && isspace(end[-1])) end--;
3232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    *end = 0;
3233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    if (*buffer != 0)
3234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      {
3235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE);
3236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      if (frc > 1) rc = frc;
3237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich        else if (frc == 0 && rc == 1) rc = 0;
3238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich      }
3239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    }
3240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (fl != stdin) fclose(fl);
3241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* After handling file-list, work through remaining arguments. Pass in the fact
3244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthat there is only one argument at top level - this suppresses the file name if
3245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichthe argument is not a directory and filenames are not otherwise forced. */
3246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichonly_one_at_top = i == argc - 1 && file_lists == NULL;
3248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfor (; i < argc; i++)
3250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  int frc = grep_or_recurse(argv[i], dee_action == dee_RECURSE,
3252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    only_one_at_top);
3253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  if (frc > 1) rc = frc;
3254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich    else if (frc == 0 && rc == 1) rc = 0;
3255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichEXIT:
3258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#ifdef SUPPORT_PCREGREP_JIT
3259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichif (jit_stack != NULL) pcre_jit_stack_free(jit_stack);
3260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif
3261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree(main_buffer);
3263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree((void *)pcretables);
3264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(patterns);
3266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(include_patterns);
3267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(include_dir_patterns);
3268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(exclude_patterns);
3269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_pattern_chain(exclude_dir_patterns);
3270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_file_chain(exclude_from);
3272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_file_chain(include_from);
3273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_file_chain(pattern_files);
3274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichfree_file_chain(file_lists);
3275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichwhile (only_matching != NULL)
3277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  {
3278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  omstr *this = only_matching;
3279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  only_matching = this->next;
3280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  free(this);
3281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich  }
3282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichpcregrep_exit(rc);
3284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichEXIT2:
3286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichrc = 2;
3287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichgoto EXIT;
3288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich}
3289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich
3290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* End of pcregrep */
3291