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 "lkc.h" 13 14 unsigned int strhash(const char *s) 15 { 16 /* fnv32 hash */ 17 unsigned int hash = 2166136261U; 18 19 for (; *s; s++) 20 hash = (hash ^ *s) * 0x01000193; 21 return hash; 22 } 23 24 /* hash table of all parsed Kconfig files */ 25 static HASHTABLE_DEFINE(file_hashtable, 1U << 11); 26 27 struct file { 28 struct hlist_node node; 29 char name[]; 30 }; 31 32 /* file already present in list? If not add it */ 33 const char *file_lookup(const char *name) 34 { 35 struct file *file; 36 size_t len; 37 int hash = strhash(name); 38 39 hash_for_each_possible(file_hashtable, file, node, hash) 40 if (!strcmp(name, file->name)) 41 return file->name; 42 43 len = strlen(name); 44 file = xmalloc(sizeof(*file) + len + 1); 45 memset(file, 0, sizeof(*file)); 46 memcpy(file->name, name, len); 47 file->name[len] = '\0'; 48 49 hash_add(file_hashtable, &file->node, hash); 50 51 str_printf(&autoconf_cmd, "\t%s \\\n", name); 52 53 return file->name; 54 } 55 56 /* Allocate initial growable string */ 57 struct gstr str_new(void) 58 { 59 struct gstr gs; 60 gs.s = xmalloc(sizeof(char) * 64); 61 gs.len = 64; 62 gs.max_width = 0; 63 strcpy(gs.s, "\0"); 64 return gs; 65 } 66 67 /* Free storage for growable string */ 68 void str_free(struct gstr *gs) 69 { 70 free(gs->s); 71 gs->s = NULL; 72 gs->len = 0; 73 } 74 75 /* Append to growable string */ 76 void str_append(struct gstr *gs, const char *s) 77 { 78 size_t l; 79 if (s) { 80 l = strlen(gs->s) + strlen(s) + 1; 81 if (l > gs->len) { 82 gs->s = xrealloc(gs->s, l); 83 gs->len = l; 84 } 85 strcat(gs->s, s); 86 } 87 } 88 89 /* Append printf formatted string to growable string */ 90 void str_printf(struct gstr *gs, const char *fmt, ...) 91 { 92 va_list ap; 93 char s[10000]; /* big enough... */ 94 va_start(ap, fmt); 95 vsnprintf(s, sizeof(s), fmt, ap); 96 str_append(gs, s); 97 va_end(ap); 98 } 99 100 /* Retrieve value of growable string */ 101 char *str_get(const struct gstr *gs) 102 { 103 return gs->s; 104 } 105 106 void *xmalloc(size_t size) 107 { 108 void *p = malloc(size); 109 if (p) 110 return p; 111 fprintf(stderr, "Out of memory.\n"); 112 exit(1); 113 } 114 115 void *xcalloc(size_t nmemb, size_t size) 116 { 117 void *p = calloc(nmemb, size); 118 if (p) 119 return p; 120 fprintf(stderr, "Out of memory.\n"); 121 exit(1); 122 } 123 124 void *xrealloc(void *p, size_t size) 125 { 126 p = realloc(p, size); 127 if (p) 128 return p; 129 fprintf(stderr, "Out of memory.\n"); 130 exit(1); 131 } 132 133 char *xstrdup(const char *s) 134 { 135 char *p; 136 137 p = strdup(s); 138 if (p) 139 return p; 140 fprintf(stderr, "Out of memory.\n"); 141 exit(1); 142 } 143 144 char *xstrndup(const char *s, size_t n) 145 { 146 char *p; 147 148 p = strndup(s, n); 149 if (p) 150 return p; 151 fprintf(stderr, "Out of memory.\n"); 152 exit(1); 153 } 154