1 /***************************************************************************
2  *  Pinfo is a ncurses based lynx style info documentation browser
3  *
4  *  Copyright (C) 1999  Przemek Borys <pborys@dione.ids.pl>
5  *  Copyright (C) 2005  Bas Zoetekouw <bas@debian.org>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of version 2 of the GNU General Public License as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful, but
12  *  WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
19  *  USA
20  ***************************************************************************/
21 
22 #include "common_includes.h"
23 
24 #ifndef ___DONT_USE_REGEXP_SEARCH___
25 #include "regex.h"
26 #include <ctype.h>
27 /* adapted partialy from midnight commander view regexp search */
28 
29 enum
30 {
31 	match_file, match_normal
32 };
33 
34 int
__regexp_search(char * pattern,char * string)35 __regexp_search(char *pattern, char *string)
36 {
37 	int match_type = match_normal;
38 	static char *old_pattern = NULL;
39 	static int old_type;
40 	regmatch_t pmatch[1];
41 	int i, flags = REG_ICASE;
42 	int rval;
43 
44 	if (!old_pattern || strcmp(old_pattern, pattern) || old_type != match_type)
45 	{
46 		if (old_pattern)
47 		{
48 			free(old_pattern);
49 			old_pattern = 0;
50 		}
51 		for (i = 0; pattern[i] != 0; i++)
52 		{
53 			if (isupper((unsigned char) pattern[i]))
54 			{
55 				flags = 0;
56 				break;
57 			}
58 		}
59 		flags |= REG_EXTENDED;
60 		if (pinfo_re_offset == -1)
61 		{
62 			pinfo_re_offset = h_regexp_num;
63 			if (!h_regexp_num)
64 				h_regexp = malloc(sizeof(regex_t));
65 			else
66 				h_regexp = realloc(h_regexp, sizeof(regex_t) *(h_regexp_num + 1));
67 		}
68 		else
69 		{
70 			regfree(&h_regexp[pinfo_re_offset]);
71 		}
72 		/* invalid regexp */
73 		if (regcomp(&h_regexp[pinfo_re_offset], pattern, flags))
74 		{
75 			return -1;
76 		}
77 		old_pattern = strdup(pattern);
78 		old_type = match_type;
79 	}
80 	rval = regexec(&h_regexp[pinfo_re_offset], string, 1, pmatch, 0);
81 	if (rval != 0)
82 		return -1;
83 	else
84 		return pmatch[0].rm_so;
85 }
86 
87 int
regexp_search(char * pattern,char * string)88 regexp_search(char *pattern, char *string)
89 {
90 	int newlines = 0, ptr_offset = -1;
91 	char *__newlines[2];
92 	char *str = string;
93 	char *start = str;
94 	while (*str)
95 	{
96 		if (*str == '\n')
97 		{
98 			__newlines[newlines] = str + 1;
99 			newlines++;
100 		}
101 		if (newlines == 2)
102 		{
103 			*str = 0;
104 			ptr_offset = __regexp_search(pattern, start);
105 			*str = '\n';
106 			newlines = 1;
107 			if (ptr_offset != -1)
108 				return (start - string) + ptr_offset;
109 			if (*(__newlines[0] + 1) != 0)
110 				start = __newlines[0] + 1;
111 			if (ptr_offset == -1)
112 			{
113 				__newlines[0] = __newlines[1];
114 			}
115 		}
116 		str++;
117 	}
118 	ptr_offset = __regexp_search(pattern, start);
119 	if (ptr_offset != -1)
120 	{
121 		return (start - string) + ptr_offset;
122 	}
123 	else
124 		return -1;
125 }
126 #else /* non-regexp version of search */
127 int
__regexp_search(char * pattern,char * string)128 __regexp_search(char *pattern, char *string)
129 {
130 	char *found = strstr(string, pattern);
131 	if (found == NULL)
132 		return -1;
133 	else
134 		return (long)(found - string);
135 }
136 
137 int
regexp_search(char * pattern,char * string)138 regexp_search(char *pattern, char *string)
139 {
140 	int newlines = 0, ptr_offset = -1;
141 	char *found;
142 	char *__newlines[2];
143 	char *str = string;
144 	char *start = str;
145 	while (*str)
146 	{
147 		if (*str == '\n')
148 		{
149 			__newlines[newlines] = str + 1;
150 			newlines++;
151 		}
152 		if (newlines == 2)
153 		{
154 			*str = 0;
155 			ptr_offset = __regexp_search(pattern, start);
156 			*str = '\n';
157 			newlines = 1;
158 			if (ptr_offset != -1)
159 				return (start - string) + ptr_offset;
160 			if (*(__newlines[0] + 1) != 0)
161 				start = __newlines[0] + 1;
162 			if (ptr_offset == -1)
163 			{
164 				__newlines[0] = __newlines[1];
165 			}
166 		}
167 		str++;
168 	}
169 	ptr_offset = __regexp_search(pattern, start);
170 	if (ptr_offset != -1)
171 	{
172 		return (start - string) + ptr_offset;
173 	}
174 	else
175 		return -1;
176 }
177 
178 #endif
179