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 (c) 1997-1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* 28 * util.c -- low-level utilities used by map*.c 29 */ 30 #include <stdio.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <stdlib.h> 34 #include "xlator.h" 35 #include "util.h" 36 #include "errlog.h" 37 38 /* 39 * String tables -- WARNING! This uses realloc to recreate tables, 40 * so always assign table_t * return value to the current 41 * table pointer, lest the table address change in the 42 * called function. 43 */ 44 static char *strset(char *, char *); 45 46 table_t * 47 create_stringtable(int size) 48 { 49 table_t *t; 50 51 /* Solaris idiom: malloc && memset. TBD. */ 52 if ((t = calloc((size_t)1, (size_t)(sizeof (table_t) + 53 ((sizeof (char *)) * size)))) == NULL) { 54 errlog(FATAL, 55 "\nOut of memory.\n" 56 "We wish to hold the whole sky,\n" 57 "But we never will.\n"); 58 } 59 t->nelem = size; 60 t->used = -1; 61 return (t); 62 } 63 64 65 table_t * 66 add_to_stringtable(table_t *t, char *value) 67 { 68 table_t *t2; 69 70 int i; 71 72 if (t == NULL) { 73 seterrline(__LINE__, __FILE__, NULL, NULL); 74 errlog(FATAL|PROGRAM, "programmer error: tried to add to " 75 "a NULL table"); 76 } 77 if (in_stringtable(t, value)) { 78 return (t); 79 } 80 ++t->used; 81 if (t->used >= t->nelem) { 82 if ((t2 = realloc(t, (size_t)(sizeof (table_t) + 83 ((sizeof (char *)) * (t->nelem + TABLE_INCREMENT))))) 84 == NULL) { 85 print_stringtable(t); 86 seterrline(__LINE__, __FILE__, NULL, NULL); 87 errlog(FATAL|PROGRAM, "out of memory extending a " 88 "string table"); 89 } 90 t = t2; 91 t->nelem += TABLE_INCREMENT; 92 for (i = t->used; i < t->nelem; ++i) { 93 t->elements[i] = NULL; 94 } 95 } 96 t->elements[t->used] = strset(t->elements[t->used], value); 97 return (t); 98 } 99 100 /* 101 * free_stringtable -- really only mark it empty for reuse. 102 */ 103 table_t * 104 free_stringtable(table_t *t) 105 { 106 107 if (t != NULL) { 108 t->used = -1; 109 } 110 return (t); 111 } 112 113 114 char * 115 get_stringtable(table_t *t, int index) 116 { 117 118 if (t == NULL) { 119 return (NULL); 120 } else if (index > t->used) { 121 return (NULL); 122 } else { 123 return (t->elements[index]); 124 } 125 } 126 127 int 128 in_stringtable(table_t *t, const char *value) 129 { 130 int i; 131 132 if (t == NULL) { 133 return (0); 134 } 135 for (i = 0; i <= t->used; ++i) { 136 if (strcmp(value, t->elements[i]) == 0) 137 return (1); 138 } 139 return (0); 140 } 141 142 143 void 144 print_stringtable(table_t *t) 145 { 146 int i; 147 148 if (t == NULL) 149 return; 150 151 errlog(VERBOSE, 152 "table size = %d elements out of %d elements/%d bytes\n", 153 t->used + 1, t->nelem, 154 sizeof (table_t) + (sizeof (char *) * t->nelem)); 155 156 for (i = 0; i <= t->used; ++i) { 157 (void) fprintf(stderr, "\t%s\n", 158 get_stringtable(t, i)); 159 } 160 } 161 162 static int 163 compare(const void *p, const void *q) 164 { 165 return (strcmp((char *)p, (char *)q)); 166 } 167 168 void 169 sort_stringtable(table_t *t) 170 { 171 172 if (t && t->used > 0) { 173 qsort((char *)t->elements, (size_t)t->used, 174 sizeof (char *), compare); 175 } 176 } 177 178 179 /* 180 * strset -- update a dynamically-allocated string or die trying. 181 */ 182 /*ARGSUSED*/ 183 static char * 184 strset(char *string, char *value) 185 { 186 size_t vlen; 187 188 assert(value != NULL, "passed a null value to strset"); 189 vlen = strlen(value); 190 if (string == NULL) { 191 /* It was never allocated, so allocate it. */ 192 if ((string = malloc(vlen + 1)) == NULL) { 193 seterrline(__LINE__, __FILE__, NULL, NULL); 194 errlog(FATAL|PROGRAM, "out of memory allocating a " 195 "string"); 196 } 197 } else if (strlen(string) < vlen) { 198 /* Reallocate bigger. */ 199 if ((string = realloc(string, vlen + 1)) == NULL) { 200 seterrline(__LINE__, __FILE__, NULL, NULL); 201 errlog(FATAL|PROGRAM, "out of memory reallocating" 202 "a string"); 203 } 204 } 205 (void) strcpy(string, value); 206 return (string); 207 } 208