xref: /linux/scripts/kconfig/util.c (revision e6a901a00822659181c93c86d8bbc2a17779fddc)
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(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