1 /* 2 * CDDL HEADER START 3 * 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. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <strings.h> 30 #include <ctype.h> 31 #include <fm/libtopo.h> 32 #include <fm/topo_mod.h> 33 #include <topo_alloc.h> 34 35 char * 36 topo_hdl_strdup(topo_hdl_t *thp, const char *s) 37 { 38 char *p; 39 40 if (s != NULL) 41 p = topo_hdl_alloc(thp, strlen(s) + 1); 42 else 43 p = NULL; 44 45 if (p != NULL) 46 (void) strcpy(p, s); 47 48 return (p); 49 } 50 51 void 52 topo_hdl_strfree(topo_hdl_t *thp, char *s) 53 { 54 if (s != NULL) 55 topo_hdl_free(thp, s, strlen(s) + 1); 56 } 57 58 char * 59 topo_mod_strdup(topo_mod_t *mod, const char *s) 60 { 61 return (topo_hdl_strdup(mod->tm_hdl, s)); 62 } 63 64 void 65 topo_mod_strfree(topo_mod_t *mod, char *s) 66 { 67 topo_hdl_strfree(mod->tm_hdl, s); 68 } 69 70 const char * 71 topo_strbasename(const char *s) 72 { 73 const char *p = strrchr(s, '/'); 74 75 if (p == NULL) 76 return (s); 77 78 return (++p); 79 } 80 81 char * 82 topo_strdirname(char *s) 83 { 84 static char slash[] = "/"; 85 static char dot[] = "."; 86 char *p; 87 88 if (s == NULL || *s == '\0') 89 return (dot); 90 91 for (p = s + strlen(s); p != s && *--p == '/'; ) 92 continue; 93 94 if (p == s && *p == '/') 95 return (slash); 96 97 while (p != s) { 98 if (*--p == '/') { 99 while (*p == '/' && p != s) 100 p--; 101 *++p = '\0'; 102 return (s); 103 } 104 } 105 106 return (dot); 107 } 108 109 ulong_t 110 topo_strhash(const char *key) 111 { 112 ulong_t g, h = 0; 113 const char *p; 114 115 for (p = key; *p != '\0'; p++) { 116 h = (h << 4) + *p; 117 118 if ((g = (h & 0xf0000000)) != 0) { 119 h ^= (g >> 24); 120 h ^= g; 121 } 122 } 123 124 return (h); 125 } 126 127 /* 128 * Transform string s inline, converting each embedded C escape sequence string 129 * to the corresponding character. For example, the substring "\n" is replaced 130 * by an inline '\n' character. The length of the resulting string is returned. 131 */ 132 size_t 133 topo_stresc2chr(char *s) 134 { 135 char *p, *q, c; 136 int esc = 0; 137 int x; 138 139 for (p = q = s; (c = *p) != '\0'; p++) { 140 if (esc) { 141 switch (c) { 142 case '0': 143 case '1': 144 case '2': 145 case '3': 146 case '4': 147 case '5': 148 case '6': 149 case '7': 150 c -= '0'; 151 p++; 152 153 if (*p >= '0' && *p <= '7') { 154 c = c * 8 + *p++ - '0'; 155 156 if (*p >= '0' && *p <= '7') 157 c = c * 8 + *p - '0'; 158 else 159 p--; 160 } else 161 p--; 162 163 *q++ = c; 164 break; 165 166 case 'a': 167 *q++ = '\a'; 168 break; 169 case 'b': 170 *q++ = '\b'; 171 break; 172 case 'f': 173 *q++ = '\f'; 174 break; 175 case 'n': 176 *q++ = '\n'; 177 break; 178 case 'r': 179 *q++ = '\r'; 180 break; 181 case 't': 182 *q++ = '\t'; 183 break; 184 case 'v': 185 *q++ = '\v'; 186 break; 187 188 case 'x': 189 for (x = 0; (c = *++p) != '\0'; ) { 190 if (c >= '0' && c <= '9') 191 x = x * 16 + c - '0'; 192 else if (c >= 'a' && c <= 'f') 193 x = x * 16 + c - 'a' + 10; 194 else if (c >= 'A' && c <= 'F') 195 x = x * 16 + c - 'A' + 10; 196 else 197 break; 198 } 199 *q++ = (char)x; 200 p--; 201 break; 202 203 case '"': 204 case '\\': 205 *q++ = c; 206 break; 207 default: 208 *q++ = '\\'; 209 *q++ = c; 210 } 211 212 esc = 0; 213 214 } else { 215 if ((esc = c == '\\') == 0) 216 *q++ = c; 217 } 218 } 219 220 *q = '\0'; 221 return ((size_t)(q - s)); 222 } 223 224 int 225 topo_strmatch(const char *s, const char *p) 226 { 227 char c; 228 229 if (p == NULL) 230 return (0); 231 232 if (s == NULL) 233 s = ""; /* treat NULL string as the empty string */ 234 235 do { 236 if ((c = *p++) == '\0') 237 return (*s == '\0'); 238 239 if (c == '*') { 240 while (*p == '*') 241 p++; /* consecutive *'s can be collapsed */ 242 243 if (*p == '\0') 244 return (1); 245 246 while (*s != '\0') { 247 if (topo_strmatch(s++, p) != 0) 248 return (1); 249 } 250 251 return (0); 252 } 253 } while (c == *s++); 254 255 return (0); 256 }