"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.1/src/regex.c" (22 Dec 2021, 5615 Bytes) of package /linux/misc/tin-2.6.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "regex.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.0_vs_2.6.1.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : regex.c
4 * Author : Jason Faultless <jason@altarstone.com>
5 * Created : 1997-02-21
6 * Updated : 2021-02-23
7 * Notes : Regular expression subroutines
8 * Credits :
9 *
10 * Copyright (c) 1997-2022 Jason Faultless <jason@altarstone.com>
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * 3. Neither the name of the copyright holder nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41
42 #ifndef TIN_H
43 # include "tin.h"
44 #endif /* !TIN_H */
45 #ifndef TCURSES_H
46 # include "tcurses.h"
47 #endif /* !TCURSES_H */
48
49 /*
50 * See if pattern is matched in string. Return TRUE or FALSE
51 * if icase=TRUE then ignore case in the compare
52 * if a precompiled regex is provided it will be used instead of pattern
53 *
54 * If you use match_regex() with full regexes within a loop you should always
55 * provide a precompiled error because if the compilation of the regex fails
56 * an error message will be display on each execution of match_regex()
57 */
58 t_bool
59 match_regex(
60 const char *string,
61 char *pattern,
62 struct regex_cache *cache,
63 t_bool icase)
64 {
65 int error;
66 struct regex_cache tmp_cache = { NULL, NULL };
67 struct regex_cache *ptr_cache;
68
69 if (!tinrc.wildcard) /* wildmat matching */
70 return wildmat(string, pattern, icase);
71
72 /* full regexes */
73 if (cache != NULL && cache->re != NULL)
74 ptr_cache = cache; /* use the provided regex cache */
75 else {
76 /* compile the regex internally */
77 if (!compile_regex(pattern, &tmp_cache, (icase ? PCRE_CASELESS : 0)))
78 return FALSE;
79 ptr_cache = &tmp_cache;
80 }
81
82 if ((error = pcre_exec(ptr_cache->re, ptr_cache->extra, string, (int) strlen(string), 0, 0, NULL, 0)) >= 0) {
83 if (ptr_cache == &tmp_cache) {
84 FreeIfNeeded(tmp_cache.re);
85 FreeIfNeeded(tmp_cache.extra);
86 }
87
88 return TRUE;
89 }
90
91 #if 0
92 /*
93 * match_regex() is mostly used within loops and we don't want to display
94 * an error message on each call
95 */
96 if (error != PCRE_ERROR_NOMATCH)
97 error_message(2, _(txt_pcre_error_num), error);
98 #endif /* 0 */
99
100 FreeIfNeeded(tmp_cache.re);
101 FreeIfNeeded(tmp_cache.extra);
102
103 return FALSE;
104 }
105
106
107 /*
108 * Compile and optimise 'regex'. Return TRUE if all went well
109 */
110 t_bool
111 compile_regex(
112 const char *regex,
113 struct regex_cache *cache,
114 int options)
115 {
116 const char *regex_errmsg = NULL;
117 int regex_errpos, my_options = options;
118
119 #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) && (defined(PCRE_MAJOR) && PCRE_MAJOR >= 4)
120 if (IS_LOCAL_CHARSET("UTF-8")) {
121 int i;
122
123 pcre_config(PCRE_CONFIG_UTF8, &i);
124 if (i)
125 my_options |= PCRE_UTF8;
126 }
127 #endif /* MULTIBYTE_ABLE && !NO_LOCALE && PCRE_MAJOR && PCRE_MAJOR >= 4 */
128
129 if ((cache->re = pcre_compile(regex, my_options, ®ex_errmsg, ®ex_errpos, NULL)) == NULL)
130 error_message(2, _(txt_pcre_error_at), regex_errmsg, regex_errpos, regex);
131 else {
132 cache->extra = pcre_study(cache->re, 0, ®ex_errmsg);
133 if (regex_errmsg != NULL) {
134 /* we failed, clean up */
135 FreeAndNull(cache->re);
136 error_message(2, _(txt_pcre_error_text), regex_errmsg);
137 } else
138 return TRUE;
139 }
140 return FALSE;
141 }
142
143
144 /*
145 * Highlight any string on 'row' that match 'regex'
146 */
147 void
148 highlight_regexes(
149 int row,
150 struct regex_cache *regex,
151 int color)
152 {
153 char *ptr;
154 int offsets[6]; /* we are not interested in any subpatterns, so 6 is sufficient */
155 int offsets_size = ARRAY_SIZE(offsets);
156 #ifdef USE_CURSES
157 char buf[LEN];
158 #else
159 char *buf;
160 #endif /* USE_CURSES */
161
162 /* Get contents of line from the screen */
163 #ifdef USE_CURSES
164 screen_contents(row, 0, buf);
165 #else
166 buf = screen[row].col;
167 #endif /* USE_CURSES */
168 ptr = buf;
169
170 /* also check for 0 as offsets[] might be too small to hold all captured subpatterns */
171 while (pcre_exec(regex->re, regex->extra, ptr, (int) strlen(ptr), 0, 0, offsets, offsets_size) >= 0) {
172 /* we have a match */
173 if (color >= 0) /* color the matching text */
174 word_highlight_string(row, (int) ((ptr - buf) + offsets[0]), offsets[1] - offsets[0], color);
175 else
176 /* inverse the matching text */
177 highlight_string(row, (int) ((ptr - buf) + offsets[0]), offsets[1] - offsets[0]);
178
179 if (!tinrc.word_h_display_marks) {
180 #ifdef USE_CURSES
181 screen_contents(row, 0, buf);
182 #endif /* USE_CURSES */
183 ptr += offsets[1] - 2;
184 } else
185 ptr += offsets[1];
186 }
187 }