diff directive.c @ 199:1d2bad7151f9

Add a -debuglog option to send an execution trace to a file. Intended to be used when debugging imake templates and other complex input, not for debugging tradcpp itself.
author David A. Holland
date Sun, 04 Sep 2016 17:14:42 -0400
parents 4c3375895c6e
children 3a25180d3a5c
line wrap: on
line diff
--- a/directive.c	Sat Dec 05 18:08:24 2015 -0500
+++ b/directive.c	Sun Sep 04 17:14:42 2016 -0400
@@ -179,11 +179,14 @@
 void
 d_if(struct lineplace *lp, struct place *p2, char *line)
 {
+	bool doprint;
 	char *expr;
 	bool val;
 	struct place p3 = *p2;
 	size_t oldlen;
 
+	doprint = ifstate->curtrue;
+
 	expr = macroexpand(p2, line, strlen(line), true);
 
 	oldlen = strlen(expr);
@@ -198,30 +201,54 @@
 	}
 	ifstate_push(&lp->current, val);
 	dostrfree(expr);
+
+	if (doprint) {
+		debuglog(&lp->current, "#if: %s",
+			  ifstate->curtrue ? "taken" : "not taken");
+	}
 }
 
 static
 void
 d_ifdef(struct lineplace *lp, struct place *p2, char *line)
 {
+	bool doprint;
+
+	doprint = ifstate->curtrue;
+
 	uncomment(line);
 	oneword("#ifdef", p2, line);
 	ifstate_push(&lp->current, macro_isdefined(line));
+
+	if (doprint) {
+		debuglog(&lp->current, "#ifdef %s: %s",
+			 line, ifstate->curtrue ? "taken" : "not taken");
+	}
 }
 
 static
 void
 d_ifndef(struct lineplace *lp, struct place *p2, char *line)
 {
+	bool doprint;
+
+	doprint = ifstate->curtrue;
+
 	uncomment(line);
 	oneword("#ifndef", p2, line);
 	ifstate_push(&lp->current, !macro_isdefined(line));
+
+	if (doprint) {
+		debuglog(&lp->current, "#ifndef %s: %s",
+			 line, ifstate->curtrue ? "taken" : "not taken");
+	}
 }
 
 static
 void
 d_elif(struct lineplace *lp, struct place *p2, char *line)
 {
+	bool doprint;
 	char *expr;
 	struct place p3 = *p2;
 	size_t oldlen;
@@ -231,6 +258,8 @@
 		complain_fail();
 	}
 
+	doprint = ifstate->curtrue;
+
 	if (ifstate->evertrue) {
 		ifstate->curtrue = false;
 	} else {
@@ -245,12 +274,19 @@
 		ifstate->evertrue = ifstate->curtrue;
 		dostrfree(expr);
 	}
+
+	if (doprint) {
+		debuglog2(&lp->current, &ifstate->startplace, "#elif: %s",
+			  ifstate->curtrue ? "taken" : "not taken");
+	}
 }
 
 static
 void
 d_else(struct lineplace *lp, struct place *p2, char *line)
 {
+	bool doprint;
+
 	(void)p2;
 	(void)line;
 
@@ -260,9 +296,16 @@
 		complain_fail();
 	}
 
+	doprint = ifstate->curtrue;
+
 	ifstate->curtrue = !ifstate->evertrue;
 	ifstate->evertrue = true;
 	ifstate->seenelse = true;
+
+	if (doprint) {
+		debuglog2(&lp->current, &ifstate->startplace, "#else: %s",
+			  ifstate->curtrue ? "taken" : "not taken");
+	}
 }
 
 static
@@ -276,6 +319,7 @@
 		complain(&lp->current, "Unmatched #endif");
 		complain_fail();
 	} else {
+		debuglog2(&lp->current, &ifstate->startplace, "#endif");
 		ifstate_pop();
 	}
 }
@@ -340,10 +384,12 @@
 	p4.column += pos;
 
 	if (argpos) {
+		debuglog(&lp->current, "Defining %s()", line);
 		macro_define_params(p2, line, &p3,
 				    line + argpos, &p4,
 				    line + pos);
 	} else {
+		debuglog(&lp->current, "Defining %s", line);
 		macro_define_plain(p2, line, &p4, line + pos);
 	}
 }
@@ -356,6 +402,7 @@
 
 	uncomment(line);
 	oneword("#undef", p2, line);
+	debuglog(&lp->current, "Undef %s", line);
 	macro_undef(line);
 }
 
@@ -371,13 +418,17 @@
 	len = strlen(line);
 	if (len > 2 && line[0] == '"' && line[len-1] == '"') {
 		line[len-1] = '\0';
+		debuglog(p, "Entering include file \"%s\"", line+1);
 		file_readquote(p, line+1);
+		debuglog(p, "Leaving include file \"%s\"", line+1);
 		line[len-1] = '"';
 		return true;
 	}
 	if (len > 2 && line[0] == '<' && line[len-1] == '>') {
 		line[len-1] = '\0';
+		debuglog(p, "Entering include file <%s>", line+1);
 		file_readbracket(p, line+1);
+		debuglog(p, "Leaving include file <%s>", line+1);
 		line[len-1] = '>';
 		return true;
 	}