/* */
This source file includes following definitions.
- strincmp
- locatestring
1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2004, 2011
3 * Tama Communications Corporation
4 *
5 * This file is part of GNU GLOBAL.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <ctype.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #else
28 #include <strings.h>
29 #endif
30
31 #include "die.h"
32 #include "locatestring.h"
33
34 /** @file
35
36 String locator: usage and memory status
37
38 'v': result pointer
39
40 @code
41 string = "ABC XYZ XYZ ABC"
42
43 pointer = locatestring(string, "XYZ", MATCH_FIRST);
44 v
45 "ABC XYZ XYZ ABC"
46
47 pointer = locatestring(string, "XYZ", MATCH_LAST);
48 v
49 "ABC XYZ XYZ ABC"
50
51 pointer = locatestring(string, "XYZ", MATCH_AT_FIRST);
52
53 "ABC XYZ XYZ ABC" (nothing pointed)
54
55 pointer = locatestring(string, "ABC", MATCH_AT_FIRST);
56 v
57 "ABC XYZ XYZ ABC" (point the following character)
58
59 pointer = locatestring(string, "ABC", MATCH_AT_LAST);
60 v
61 "ABC XYZ XYZ ABC"
62
63 pointer = locatestring(string, "ABC XYZ XYZ ABC", MATCH_COMPLETE);
64 v
65 "ABC XYZ XYZ ABC"
66
67 pointer = locatestring(string, "xyZ", MATCH_FIRST|IGNORE_CASE);
68 v
69 "ABC XYZ XYZ ABC"
70 @endcode
71 */
72
73 /**
74 * strincmp: strncmp with ignoring case.
75 *
76 * Interface is same with @NAME{strncmp}.
77 */
78 static int
79 strincmp(const char *string, const char *pattern, size_t len)
80 {
81 unsigned char s, p;
82
83 while (len--) {
84 /*
85 * In some systems, tolower() are #define macros,
86 * where the argument gets evaluated more than once.
87 */
88 s = tolower((unsigned char)*string);
89 p = tolower((unsigned char)*pattern);
90 if (s != p)
91 return s - p;
92 if (s == 0)
93 break;
94 string++;
95 pattern++;
96 }
97 return 0;
98 }
99
100 /**
101 * locatestring: locate pattern from string
102 *
103 * @param[in] string string
104 * @param[in] pattern pattern
105 * @param[in] flag MATCH_FIRST: match first <br>
106 * MATCH_AT_FIRST: match only at first column <br>
107 * MATCH_LAST: match last <br>
108 * MATCH_AT_LAST: match only at last column <br>
109 * MATCH_COMPLETE match completely <br>
110 * IGNORE_CASE: Ignore case
111 * @return pointer or NULL
112 * If the flag == MATCH_AT_FIRST then the pointer <br>
113 * points the following character of the matched <br>
114 * string, else points at the head of it.
115 *
116 * This function is made to avoid compatibility problems.
117 */
118 char *
119 locatestring(const char *string, const char *pattern, int flag)
120 {
121 int plen = strlen(pattern);
122 const char *p = NULL;
123 int (*cmpfunc) (const char *, const char*, size_t);
124
125 cmpfunc = (flag & IGNORE_CASE) ? strincmp : strncmp;
126 flag &= ~IGNORE_CASE;
127
128 if (flag == MATCH_COMPLETE) {
129 if (strlen(string) == plen && !(*cmpfunc)(string, pattern, plen))
130 p = string;
131 } else if (flag == MATCH_AT_FIRST) {
132 if (!(*cmpfunc)(string, pattern, plen))
133 p = string + plen;
134 } else if (flag == MATCH_AT_LAST) {
135 int slen = strlen(string);
136
137 if (slen >= plen) {
138 string += (slen - plen);
139 if (!(*cmpfunc)(string, pattern, plen))
140 p = string;
141 }
142 } else if (flag == MATCH_FIRST || flag == MATCH_LAST) {
143 int slen = strlen(string);
144
145 for (; *string; string++, slen--) {
146 if (slen < plen)
147 break;
148 if (!(*cmpfunc)(string, pattern, plen)) {
149 p = string;
150 if (flag == MATCH_FIRST)
151 break;
152 }
153 }
154 } else {
155 die("usage error of locatestring() (flag = %d).", flag);
156 }
157 return (char *)p;
158 }
/* */