summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwlestes <wlestes>2012-03-23 19:15:36 +0000
committerwlestes <wlestes>2012-03-23 19:15:36 +0000
commit7d51c9db23ae56aa2ddca5d6c0190e6f429f46dd (patch)
treecc3202219ef973ecd9cab4edb145fd112ca43e60
parent8763c3cf88e4b89c8fb9a352df605282468c3f13 (diff)
downloadflex-7d51c9db23ae56aa2ddca5d6c0190e6f429f46dd.tar.gz
escape backslashes in #line filenames in %top section; resolves #3212400; patch submitted by scfc_de
-rw-r--r--buf.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/buf.c b/buf.c
index c051295..e5deb4e 100644
--- a/buf.c
+++ b/buf.c
@@ -90,13 +90,20 @@ struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s)
*/
struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno)
{
- char *t, *fmt = "#line %d \"%s\"\n";
- size_t tsz;
-
- t = flex_alloc (tsz = strlen (fmt) + strlen (filename) + (int)(1 + log10(lineno>=0?lineno:-lineno)) + 1);
+ char *dst, *src, *t;
+
+ t = flex_alloc (strlen ("#line \"\"\n") + /* constant parts */
+ 2 * strlen (filename) + /* filename with possibly all backslashes escaped */
+ (int) (1 + log10 (abs (lineno))) + /* line number */
+ 1); /* NUL */
if (!t)
- flexfatal (_("Allocation of buffer for line directive failed"));
- snprintf (t, tsz, fmt, lineno, filename);
+ flexfatal (_("Allocation of buffer for line directive failed"));
+ for (dst = t + sprintf (t, "#line %d \"", lineno), src = filename; *src; *dst++ = *src++)
+ if (*src == '\\') /* escape backslashes */
+ *dst++ = '\\';
+ *dst++ = '"';
+ *dst++ = '\n';
+ *dst = '\0';
buf = buf_strappend (buf, t);
flex_free (t);
return buf;