/* vars.c */ #include "config.h" /* * This file is part of TeenyMUD II. * Copyright(C) 1993, 1994, 1995 by Jason Downs. * All rights reserved. * * TeenyMUD II is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * TeenyMUD II is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file 'COPYING'); if not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * */ /* AIX requires this to be the first thing in the file. */ #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #ifdef HAVE_ALLOCA_H #include <alloca.h> #else /* not HAVE_ALLOCA_H */ #ifdef _AIX #pragma alloca #endif /* not _AIX */ #endif /* not HAVE_ALLOCA_H */ #endif /* not __GNUC__ */ #include <stdio.h> #include <sys/types.h> #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif /* HAVE_STRING_H */ #include <ctype.h> #include "conf.h" #include "teeny.h" #include "externs.h" #include "hash/hash.h" /* 'variable' handlers / 'list' creation and handlers */ static int Var_Inited = 0; static Hash_Table Var_Table; char *var_get(owner, key) int owner; char *key; { char sbuff[32], *buff; register Hash_Entry *entry; if((key == (char *)NULL) || (key[0] == '\0')) return((char *)NULL); if(!Var_Inited) return((char *)NULL); snprintf(sbuff, sizeof(sbuff), "%d-", owner); buff = (char *)alloca(strlen(sbuff) + strlen(key) + 1); if(buff == (char *)NULL) panic("var_get: stack allocation failed.\n"); strcpy(buff, sbuff); strcat(buff, key); entry = Hash_FindEntry(&Var_Table, buff); if(entry == (Hash_Entry *)NULL) return((char *)NULL); return((char *)Hash_GetValue(entry)); } void var_delete(owner, key) int owner; char *key; { char sbuff[32], *buff; register Hash_Entry *entry; if((key == (char *)NULL) || (key[0] == '\0')) return; if(!Var_Inited) return; snprintf(sbuff, sizeof(sbuff), "%d-", owner); buff = (char *)alloca(strlen(sbuff) + strlen(key) + 1); if(buff == (char *)NULL) panic("var_get: stack allocation failed.\n"); strcpy(buff, sbuff); strcat(buff, key); entry = Hash_FindEntry(&Var_Table, buff); if(entry == (Hash_Entry *)NULL) return; ty_free((VOID *)Hash_GetValue(entry)); Hash_DeleteEntry(&Var_Table, entry); } void var_set(owner, key, value) int owner; char *key, *value; { char sbuff[32], *buff; register Hash_Entry *entry; int new; if((key == (char *)NULL) || (key[0] == '\0') || (value == (char *)NULL) || (value[0] == '\0')) return; if(!Var_Inited) { Hash_InitTable(&Var_Table, 0, HASH_STRING_KEYS); Var_Inited = 1; } snprintf(sbuff, sizeof(sbuff), "%d-", owner); buff = (char *)alloca(strlen(sbuff) + strlen(key) + 1); if(buff == (char *)NULL) panic("var_set: stack allocation failed.\n"); strcpy(buff, sbuff); strcat(buff, key); entry = Hash_CreateEntry(&Var_Table, buff, &new); if(!new) ty_free((VOID *)Hash_GetValue(entry)); Hash_SetValue(entry, (char *)ty_strdup(value, "var_set.value")); } /* add an element to a list, doing proper quoting and all. */ static char slist_ret[BUFFSIZ]; /* elem size limit */ void slist_add(elem, buffer, bufsiz) char *elem, *buffer; int bufsiz; { int quote = 0; int first = 0; register char *ptr, *bptr; if((elem == (char *)NULL) || (buffer == (char *)NULL)) return; /* is the buffer empty? */ if((buffer[0] == '\0') && bufsiz) { strcpy(buffer, "{}"); first++; } else if((buffer[0] == '{') && (buffer[1] == '}')) { first++; } bufsiz -= strlen(buffer); if(bufsiz <= 0) return; /* should we quote it? */ ptr = elem; while(*ptr != '\0') { if(isspace(*ptr)) quote++; ptr++; } /* add as much of the element in as we can. */ bptr = &buffer[strlen(buffer)-1]; /* remove trailing brace */ ptr = elem; /* insert any leading space and any needing quote. */ if(!first) { *bptr++ = ' '; bufsiz--; } if(quote) { *bptr++ = '\"'; bufsiz--; } while((*ptr != '\0') && (bufsiz > 2) && ((ptr - elem) < sizeof(slist_ret))) { if((*ptr == '\"') || (*ptr == '{') || (*ptr == '}') || (*ptr == '[') || (*ptr == ']')) { *bptr++ = '\\'; bufsiz--; } *bptr++ = *ptr++; bufsiz--; } if(quote) { *bptr++ = '\"'; bufsiz--; } *bptr++ = '}'; *bptr = '\0'; } /* return the next (or first) element of a list. */ char *slist_next(list, nptr) char *list, **nptr; { register char *ptr, *bptr; if(list == (char *)NULL) return((char *)NULL); if(*nptr == (char *)NULL) { for(ptr = list; (*ptr != '\0') && ((*ptr == '{') || isspace(*ptr)); ptr++); if(*ptr == '\0') return((char *)NULL); } else ptr = *nptr; if((*ptr == '\0') || (*ptr == '}')) return((char *)NULL); while((*ptr != '\0') && isspace(*ptr)) ptr++; if(*ptr == '\0') return((char *)NULL); bptr = slist_ret; if(*ptr == '\"') { /* quoted element */ /* eat leading quote. */ ptr++; while((*ptr != '\0') && (*ptr != '\"') && (*ptr != '}') && ((bptr - slist_ret) < sizeof(slist_ret))) { if(*ptr == '\\') { ptr++; if(*ptr != '\0') *bptr++ = *ptr++; } else *bptr++ = *ptr++; } if((bptr - slist_ret) >= sizeof(slist_ret)) { /* try to find the end of this element */ while((*ptr != '\0') && (*ptr != '\"') && (ptr[-1] != '\\')) ptr++; } /* find the beginning of the next element. */ if(*ptr == '\"') ptr++; while((*ptr != '\0') && (*ptr != '\"') && isspace(*ptr)) ptr++; } else { while((*ptr != '\0') && !isspace(*ptr) && (*ptr != '}') && ((bptr - slist_ret) < sizeof(slist_ret))) { if(*ptr == '\\') { ptr++; if(*ptr != '\0') *bptr++ = *ptr++; } else *bptr++ = *ptr++; } if((bptr - slist_ret) >= sizeof(slist_ret)) { /* try to find the end of this element */ while((*ptr != '\0') && !isspace(*ptr) && (ptr[-1] != '\\')) ptr++; } } *bptr = '\0'; *nptr = ptr; /* point at terminating quote or space! */ return(slist_ret); }