13 * Read one logical line from a configuration file.
15 * Line endings may be escaped with backslashes, to form one logical line from
16 * several physical lines. No end of line character(s) are included in the
19 * If linenum is not NULL, it is incremented by the number of physical lines
20 * which have been read.
22 char *getline_wrapped(FILE *file, unsigned int *linenum)
26 char *buf = NOFAIL(malloc(size));
28 int ch = getc_unlocked(file);
36 /* else fall through */
42 buf = NOFAIL(realloc(buf, size + 1));
47 ch = getc_unlocked(file);
54 /* else fall through */
61 buf = NOFAIL(realloc(buf, size));
68 * Convert filename to the module name. Works if filename == modname, too.
70 void filename2modname(char *modname, const char *filename)
72 const char *afterslash;
75 afterslash = my_basename(filename);
77 /* Convert to underscores, stop at first . */
78 for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
79 if (afterslash[i] == '-')
82 modname[i] = afterslash[i];
88 * Replace dashes with underscores.
89 * Dashes inside character range patterns (e.g. [0-9]) are left unchanged.
91 char *underscores(char *string)
98 for (i = 0; string[i]; i++) {
105 warn("Unmatched bracket in %s\n", string);
109 i += strcspn(&string[i], "]");
111 warn("Unmatched bracket in %s\n", string);
119 * strtbl_add - add a string to a string table.
121 * @str: string to add
122 * @tbl: current string table. NULL = allocate new table
124 * Allocates an array of pointers to strings.
125 * The strings themselves are not actually kept in the table.
127 * Returns reallocated and updated string table. NULL = out of memory.
129 * Implementation note: The string table is designed to be lighter-weight
130 * and faster than a more conventional linked list that stores the strings
131 * in the list elements, as it does far fewer malloc/realloc calls
132 * and avoids copying entirely.
134 struct string_table *strtbl_add(const char *str, struct string_table *tbl)
137 const char max = 100;
138 tbl = malloc(sizeof(*tbl) + sizeof(char *) * max);
144 if (tbl->cnt >= tbl->max) {
146 tbl = realloc(tbl, sizeof(*tbl) + sizeof(char *) * tbl->max);
150 tbl->str[tbl->cnt] = str;
157 * strtbl_free - string table destructor
159 void strtbl_free(struct string_table *tbl)
165 * Get the basename in a pathname.
166 * Unlike the standard implementation, this does not copy the string.
168 char *my_basename(const char *path)
170 const char *base = strrchr(path, '/');
172 return (char *) base + 1;
173 return (char *) path;
177 * Find the next string in an ELF section.
179 const char *next_string(const char *string, unsigned long *secsize)
181 /* Skip non-zero chars */
184 if ((*secsize)-- <= 1)
188 /* Skip any zero padding. */
191 if ((*secsize)-- <= 1)
198 * Get CPU endianness. 0 = unknown, 1 = ELFDATA2LSB = little, 2 = ELFDATA2MSB = big
200 int __attribute__ ((pure)) native_endianness()
202 /* Encoding the endianness enums in a string and then reading that
203 * string as a 32-bit int, returns the correct endianness automagically.
205 return (char) *((uint32_t*)("\1\0\0\2"));
209 * Compare "string" with extended regex "pattern". Include backward compatible
210 * matching of "*" as a wildcard by replacing it with ".*" automatically.
212 int regex_match(const char *string, const char *pattern)
218 /* backward compatibility with old "match" code */
219 if (strncmp("*", pattern, 1) != 0)
220 fix_pattern = (char *)pattern;
222 fix_pattern = ".*"; /* match everything */
224 if (regcomp(&re, fix_pattern, REG_EXTENDED|REG_NOSUB) != 0)
225 return 0; /* alloc failure */
227 status = regexec(&re, string, (size_t) 0, NULL, 0);
231 return 0; /* no match */
233 return 1; /* match */