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 */