1*753d2d2eSraf /* 2*753d2d2eSraf * CDDL HEADER START 3*753d2d2eSraf * 4*753d2d2eSraf * The contents of this file are subject to the terms of the 5*753d2d2eSraf * Common Development and Distribution License, Version 1.0 only 6*753d2d2eSraf * (the "License"). You may not use this file except in compliance 7*753d2d2eSraf * with the License. 8*753d2d2eSraf * 9*753d2d2eSraf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*753d2d2eSraf * or http://www.opensolaris.org/os/licensing. 11*753d2d2eSraf * See the License for the specific language governing permissions 12*753d2d2eSraf * and limitations under the License. 13*753d2d2eSraf * 14*753d2d2eSraf * When distributing Covered Code, include this CDDL HEADER in each 15*753d2d2eSraf * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*753d2d2eSraf * If applicable, add the following below this CDDL HEADER, with the 17*753d2d2eSraf * fields enclosed by brackets "[]" replaced with your own identifying 18*753d2d2eSraf * information: Portions Copyright [yyyy] [name of copyright owner] 19*753d2d2eSraf * 20*753d2d2eSraf * CDDL HEADER END 21*753d2d2eSraf */ 22*753d2d2eSraf /* 23*753d2d2eSraf * Copyright (c) 1997-1999 by Sun Microsystems, Inc. 24*753d2d2eSraf * All rights reserved. 25*753d2d2eSraf */ 26*753d2d2eSraf #pragma ident "%Z%%M% %I% %E% SMI" 27*753d2d2eSraf 28*753d2d2eSraf /* 29*753d2d2eSraf * util.c -- low-level utilities used by map*.c 30*753d2d2eSraf */ 31*753d2d2eSraf #include <stdio.h> 32*753d2d2eSraf #include <string.h> 33*753d2d2eSraf #include <errno.h> 34*753d2d2eSraf #include <stdlib.h> 35*753d2d2eSraf #include "xlator.h" 36*753d2d2eSraf #include "util.h" 37*753d2d2eSraf #include "errlog.h" 38*753d2d2eSraf 39*753d2d2eSraf /* 40*753d2d2eSraf * String tables -- WARNING! This uses realloc to recreate tables, 41*753d2d2eSraf * so always assign table_t * return value to the current 42*753d2d2eSraf * table pointer, lest the table address change in the 43*753d2d2eSraf * called function. 44*753d2d2eSraf */ 45*753d2d2eSraf static char *strset(char *, char *); 46*753d2d2eSraf 47*753d2d2eSraf table_t * 48*753d2d2eSraf create_stringtable(int size) 49*753d2d2eSraf { 50*753d2d2eSraf table_t *t; 51*753d2d2eSraf 52*753d2d2eSraf /* Solaris idiom: malloc && memset. TBD. */ 53*753d2d2eSraf if ((t = calloc((size_t)1, (size_t)(sizeof (table_t) + 54*753d2d2eSraf ((sizeof (char *)) * size)))) == NULL) { 55*753d2d2eSraf errlog(FATAL, 56*753d2d2eSraf "\nOut of memory.\n" 57*753d2d2eSraf "We wish to hold the whole sky,\n" 58*753d2d2eSraf "But we never will.\n"); 59*753d2d2eSraf } 60*753d2d2eSraf t->nelem = size; 61*753d2d2eSraf t->used = -1; 62*753d2d2eSraf return (t); 63*753d2d2eSraf } 64*753d2d2eSraf 65*753d2d2eSraf 66*753d2d2eSraf table_t * 67*753d2d2eSraf add_to_stringtable(table_t *t, char *value) 68*753d2d2eSraf { 69*753d2d2eSraf table_t *t2; 70*753d2d2eSraf 71*753d2d2eSraf int i; 72*753d2d2eSraf 73*753d2d2eSraf if (t == NULL) { 74*753d2d2eSraf seterrline(__LINE__, __FILE__, NULL, NULL); 75*753d2d2eSraf errlog(FATAL|PROGRAM, "programmer error: tried to add to " 76*753d2d2eSraf "a NULL table"); 77*753d2d2eSraf } 78*753d2d2eSraf if (in_stringtable(t, value)) { 79*753d2d2eSraf return (t); 80*753d2d2eSraf } 81*753d2d2eSraf ++t->used; 82*753d2d2eSraf if (t->used >= t->nelem) { 83*753d2d2eSraf if ((t2 = realloc(t, (size_t)(sizeof (table_t) + 84*753d2d2eSraf ((sizeof (char *)) * (t->nelem + TABLE_INCREMENT))))) 85*753d2d2eSraf == NULL) { 86*753d2d2eSraf print_stringtable(t); 87*753d2d2eSraf seterrline(__LINE__, __FILE__, NULL, NULL); 88*753d2d2eSraf errlog(FATAL|PROGRAM, "out of memory extending a " 89*753d2d2eSraf "string table"); 90*753d2d2eSraf } 91*753d2d2eSraf t = t2; 92*753d2d2eSraf t->nelem += TABLE_INCREMENT; 93*753d2d2eSraf for (i = t->used; i < t->nelem; ++i) { 94*753d2d2eSraf t->elements[i] = NULL; 95*753d2d2eSraf } 96*753d2d2eSraf } 97*753d2d2eSraf t->elements[t->used] = strset(t->elements[t->used], value); 98*753d2d2eSraf return (t); 99*753d2d2eSraf } 100*753d2d2eSraf 101*753d2d2eSraf /* 102*753d2d2eSraf * free_stringtable -- really only mark it empty for reuse. 103*753d2d2eSraf */ 104*753d2d2eSraf table_t * 105*753d2d2eSraf free_stringtable(table_t *t) 106*753d2d2eSraf { 107*753d2d2eSraf 108*753d2d2eSraf if (t != NULL) { 109*753d2d2eSraf t->used = -1; 110*753d2d2eSraf } 111*753d2d2eSraf return (t); 112*753d2d2eSraf } 113*753d2d2eSraf 114*753d2d2eSraf 115*753d2d2eSraf char * 116*753d2d2eSraf get_stringtable(table_t *t, int index) 117*753d2d2eSraf { 118*753d2d2eSraf 119*753d2d2eSraf if (t == NULL) { 120*753d2d2eSraf return (NULL); 121*753d2d2eSraf } else if (index > t->used) { 122*753d2d2eSraf return (NULL); 123*753d2d2eSraf } else { 124*753d2d2eSraf return (t->elements[index]); 125*753d2d2eSraf } 126*753d2d2eSraf } 127*753d2d2eSraf 128*753d2d2eSraf int 129*753d2d2eSraf in_stringtable(table_t *t, const char *value) 130*753d2d2eSraf { 131*753d2d2eSraf int i; 132*753d2d2eSraf 133*753d2d2eSraf if (t == NULL) { 134*753d2d2eSraf return (0); 135*753d2d2eSraf } 136*753d2d2eSraf for (i = 0; i <= t->used; ++i) { 137*753d2d2eSraf if (strcmp(value, t->elements[i]) == 0) 138*753d2d2eSraf return (1); 139*753d2d2eSraf } 140*753d2d2eSraf return (0); 141*753d2d2eSraf } 142*753d2d2eSraf 143*753d2d2eSraf 144*753d2d2eSraf void 145*753d2d2eSraf print_stringtable(table_t *t) 146*753d2d2eSraf { 147*753d2d2eSraf int i; 148*753d2d2eSraf 149*753d2d2eSraf if (t == NULL) 150*753d2d2eSraf return; 151*753d2d2eSraf 152*753d2d2eSraf errlog(VERBOSE, 153*753d2d2eSraf "table size = %d elements out of %d elements/%d bytes\n", 154*753d2d2eSraf t->used + 1, t->nelem, 155*753d2d2eSraf sizeof (table_t) + (sizeof (char *) * t->nelem)); 156*753d2d2eSraf 157*753d2d2eSraf for (i = 0; i <= t->used; ++i) { 158*753d2d2eSraf (void) fprintf(stderr, "\t%s\n", 159*753d2d2eSraf get_stringtable(t, i)); 160*753d2d2eSraf } 161*753d2d2eSraf } 162*753d2d2eSraf 163*753d2d2eSraf static int 164*753d2d2eSraf compare(const void *p, const void *q) 165*753d2d2eSraf { 166*753d2d2eSraf return (strcmp((char *)p, (char *)q)); 167*753d2d2eSraf } 168*753d2d2eSraf 169*753d2d2eSraf void 170*753d2d2eSraf sort_stringtable(table_t *t) 171*753d2d2eSraf { 172*753d2d2eSraf 173*753d2d2eSraf if (t && t->used > 0) { 174*753d2d2eSraf qsort((char *)t->elements, (size_t)t->used, 175*753d2d2eSraf sizeof (char *), compare); 176*753d2d2eSraf } 177*753d2d2eSraf } 178*753d2d2eSraf 179*753d2d2eSraf 180*753d2d2eSraf /* 181*753d2d2eSraf * strset -- update a dynamically-allocated string or die trying. 182*753d2d2eSraf */ 183*753d2d2eSraf /*ARGSUSED*/ 184*753d2d2eSraf static char * 185*753d2d2eSraf strset(char *string, char *value) 186*753d2d2eSraf { 187*753d2d2eSraf size_t vlen; 188*753d2d2eSraf 189*753d2d2eSraf assert(value != NULL, "passed a null value to strset"); 190*753d2d2eSraf vlen = strlen(value); 191*753d2d2eSraf if (string == NULL) { 192*753d2d2eSraf /* It was never allocated, so allocate it. */ 193*753d2d2eSraf if ((string = malloc(vlen + 1)) == NULL) { 194*753d2d2eSraf seterrline(__LINE__, __FILE__, NULL, NULL); 195*753d2d2eSraf errlog(FATAL|PROGRAM, "out of memory allocating a " 196*753d2d2eSraf "string"); 197*753d2d2eSraf } 198*753d2d2eSraf } else if (strlen(string) < vlen) { 199*753d2d2eSraf /* Reallocate bigger. */ 200*753d2d2eSraf if ((string = realloc(string, vlen + 1)) == NULL) { 201*753d2d2eSraf seterrline(__LINE__, __FILE__, NULL, NULL); 202*753d2d2eSraf errlog(FATAL|PROGRAM, "out of memory reallocating" 203*753d2d2eSraf "a string"); 204*753d2d2eSraf } 205*753d2d2eSraf } 206*753d2d2eSraf (void) strcpy(string, value); 207*753d2d2eSraf return (string); 208*753d2d2eSraf } 209