Home | History | Annotate | Download | only in common
      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 }
    257