1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org> 4 * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org> 5 */ 6 7 #include <stdarg.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include <hashtable.h> 12 #include <xalloc.h> 13 #include "lkc.h" 14 15 unsigned int strhash(const char *s) 16 { 17 /* fnv32 hash */ 18 unsigned int hash = 2166136261U; 19 20 for (; *s; s++) 21 hash = (hash ^ *s) * 0x01000193; 22 return hash; 23 } 24 25 /* hash table of all parsed Kconfig files */ 26 static HASHTABLE_DEFINE(file_hashtable, 1U << 11); 27 28 struct file { 29 struct hlist_node node; 30 char name[]; 31 }; 32 33 /* file already present in list? If not add it */ 34 const char *file_lookup(const char *name) 35 { 36 struct file *file; 37 size_t len; 38 int hash = strhash(name); 39 40 hash_for_each_possible(file_hashtable, file, node, hash) 41 if (!strcmp(name, file->name)) 42 return file->name; 43 44 len = strlen(name); 45 file = xmalloc(sizeof(*file) + len + 1); 46 memset(file, 0, sizeof(*file)); 47 memcpy(file->name, name, len); 48 file->name[len] = '\0'; 49 50 hash_add(file_hashtable, &file->node, hash); 51 52 str_printf(&autoconf_cmd, "\t%s \\\n", name); 53 54 return file->name; 55 } 56 57 /* Allocate initial growable string */ 58 struct gstr str_new(void) 59 { 60 struct gstr gs; 61 gs.s = xmalloc(sizeof(char) * 64); 62 gs.len = 64; 63 gs.max_width = 0; 64 strcpy(gs.s, "\0"); 65 return gs; 66 } 67 68 /* Free storage for growable string */ 69 void str_free(struct gstr *gs) 70 { 71 free(gs->s); 72 gs->s = NULL; 73 gs->len = 0; 74 } 75 76 /* Append to growable string */ 77 void str_append(struct gstr *gs, const char *s) 78 { 79 size_t l; 80 if (s) { 81 l = strlen(gs->s) + strlen(s) + 1; 82 if (l > gs->len) { 83 gs->s = xrealloc(gs->s, l); 84 gs->len = l; 85 } 86 strcat(gs->s, s); 87 } 88 } 89 90 /* Append printf formatted string to growable string */ 91 void str_printf(struct gstr *gs, const char *fmt, ...) 92 { 93 va_list ap; 94 char s[10000]; /* big enough... */ 95 va_start(ap, fmt); 96 vsnprintf(s, sizeof(s), fmt, ap); 97 str_append(gs, s); 98 va_end(ap); 99 } 100 101 /* Retrieve value of growable string */ 102 char *str_get(const struct gstr *gs) 103 { 104 return gs->s; 105 } 106