dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fm / fmd / common / fmd_string.c
blobfb5acc46944dbbb6c32fde260b0c3f05bf1b87ac
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <strings.h>
30 #include <ctype.h>
32 #include <fmd_string.h>
34 char *
35 fmd_strdup(const char *s, int flags)
37 char *p;
39 if (s != NULL)
40 p = fmd_alloc(strlen(s) + 1, flags);
41 else
42 p = NULL;
44 if (p != NULL)
45 (void) strcpy(p, s);
47 return (p);
50 void
51 fmd_strfree(char *s)
53 if (s != NULL)
54 fmd_free(s, strlen(s) + 1);
57 const char *
58 fmd_strbasename(const char *s)
60 const char *p = strrchr(s, '/');
62 if (p == NULL)
63 return (s);
65 return (++p);
68 char *
69 fmd_strdirname(char *s)
71 static char slash[] = "/";
72 static char dot[] = ".";
73 char *p;
75 if (s == NULL || *s == '\0')
76 return (dot);
78 for (p = s + strlen(s); p != s && *--p == '/'; )
79 continue;
81 if (p == s && *p == '/')
82 return (slash);
84 while (p != s) {
85 if (*--p == '/') {
86 while (*p == '/' && p != s)
87 p--;
88 *++p = '\0';
89 return (s);
93 return (dot);
96 ulong_t
97 fmd_strhash(const char *key)
99 ulong_t g, h = 0;
100 const char *p;
102 for (p = key; *p != '\0'; p++) {
103 h = (h << 4) + *p;
105 if ((g = (h & 0xf0000000)) != 0) {
106 h ^= (g >> 24);
107 h ^= g;
111 return (h);
115 * Transform string s inline, converting each embedded C escape sequence string
116 * to the corresponding character. For example, the substring "\n" is replaced
117 * by an inline '\n' character. The length of the resulting string is returned.
119 size_t
120 fmd_stresc2chr(char *s)
122 char *p, *q, c;
123 int esc = 0;
124 int x;
126 for (p = q = s; (c = *p) != '\0'; p++) {
127 if (esc) {
128 switch (c) {
129 case '0':
130 case '1':
131 case '2':
132 case '3':
133 case '4':
134 case '5':
135 case '6':
136 case '7':
137 c -= '0';
138 p++;
140 if (*p >= '0' && *p <= '7') {
141 c = c * 8 + *p++ - '0';
143 if (*p >= '0' && *p <= '7')
144 c = c * 8 + *p - '0';
145 else
146 p--;
147 } else
148 p--;
150 *q++ = c;
151 break;
153 case 'a':
154 *q++ = '\a';
155 break;
156 case 'b':
157 *q++ = '\b';
158 break;
159 case 'f':
160 *q++ = '\f';
161 break;
162 case 'n':
163 *q++ = '\n';
164 break;
165 case 'r':
166 *q++ = '\r';
167 break;
168 case 't':
169 *q++ = '\t';
170 break;
171 case 'v':
172 *q++ = '\v';
173 break;
175 case 'x':
176 for (x = 0; (c = *++p) != '\0'; ) {
177 if (c >= '0' && c <= '9')
178 x = x * 16 + c - '0';
179 else if (c >= 'a' && c <= 'f')
180 x = x * 16 + c - 'a' + 10;
181 else if (c >= 'A' && c <= 'F')
182 x = x * 16 + c - 'A' + 10;
183 else
184 break;
186 *q++ = (char)x;
187 p--;
188 break;
190 case '"':
191 case '\\':
192 *q++ = c;
193 break;
194 default:
195 *q++ = '\\';
196 *q++ = c;
199 esc = 0;
201 } else {
202 if ((esc = c == '\\') == 0)
203 *q++ = c;
207 *q = '\0';
208 return ((size_t)(q - s));
212 * We require that identifiers for buffers, statistics, and properties conform
213 * to the regular expression [a-zA-Z0-9\-_.]. If check_prefixes is set, we
214 * also flag strings that begin with a set of prefixes reserved for use by fmd.
216 const char *
217 fmd_strbadid(const char *s, int check_prefixes)
219 const char *s0 = s;
220 int c = *s++;
222 while ((c = *s++) != '\0') {
223 if (!isupper(c) && !islower(c) &&
224 !isdigit(c) && c != '-' && c != '_' && c != '.')
225 return (s - 1);
228 if (check_prefixes && (s0[0] == '_' || s0[0] == '.' ||
229 strncmp(s0, "fmd_", 4) == 0 || strncmp(s0, "FMD_", 4) == 0 ||
230 strncmp(s0, "fmd.", 4) == 0 || strncmp(s0, "FMD.", 4) == 0))
231 return (s0);
233 return (NULL);
237 fmd_strmatch(const char *s, const char *p)
239 char c;
241 if (p == NULL)
242 return (0);
244 if (s == NULL)
245 s = ""; /* treat NULL string as the empty string */
247 do {
248 if ((c = *p++) == '\0')
249 return (*s == '\0');
251 if (c == '*') {
252 while (*p == '*')
253 p++; /* consecutive *'s can be collapsed */
255 if (*p == '\0')
256 return (1);
258 while (*s != '\0') {
259 if (fmd_strmatch(s++, p) != 0)
260 return (1);
263 return (0);
265 } while (c == *s++);
267 return (0);