- Avoid the expensive calloc() when creating a macro expansion buffer,
malloc() suffices just as well as long as we initialize the first
byte in the buffer. This is easily visible on wall-clock times.
- Avoid recalculating source string length: when caller doesn't
pass slen, we always calculate the string length for creating
a terminated copy, no need to redo it...
- Add a warning comment about the seemingly obvious optimization
breaking macro undefining itself, this is starting to look like
a recurring theme :)
(cherry picked from commit
c012a7698537ac446b87d636d8d835ae0fe78fdb)
int chkexist;
char *source = NULL;
- /* Handle non-terminated substrings by creating a terminated copy */
+ /*
+ * Always make a (terminated) copy of the source string.
+ * Beware: avoiding the copy when src is known \0-terminated seems like
+ * an obvious opportunity for optimization, but doing that breaks
+ * a special case of macro undefining itself.
+ */
if (!slen)
slen = strlen(src);
source = xmalloc(slen + 1);
s = source;
if (mb->buf == NULL) {
- size_t blen = MACROBUFSIZ + strlen(s);
- mb->buf = xcalloc(blen + 1, sizeof(*mb->buf));
+ size_t blen = MACROBUFSIZ + slen;
+ mb->buf = xmalloc(blen + 1);
+ mb->buf[0] = '\0';
mb->tpos = 0;
mb->nb = blen;
}