comparison 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
comparison
equal deleted inserted replaced
198:4158b974e23f 199:1d2bad7151f9
177 177
178 static 178 static
179 void 179 void
180 d_if(struct lineplace *lp, struct place *p2, char *line) 180 d_if(struct lineplace *lp, struct place *p2, char *line)
181 { 181 {
182 bool doprint;
182 char *expr; 183 char *expr;
183 bool val; 184 bool val;
184 struct place p3 = *p2; 185 struct place p3 = *p2;
185 size_t oldlen; 186 size_t oldlen;
186 187
188 doprint = ifstate->curtrue;
189
187 expr = macroexpand(p2, line, strlen(line), true); 190 expr = macroexpand(p2, line, strlen(line), true);
188 191
189 oldlen = strlen(expr); 192 oldlen = strlen(expr);
190 uncomment(expr); 193 uncomment(expr);
191 /* trim to fit, so the malloc debugging won't complain */ 194 /* trim to fit, so the malloc debugging won't complain */
196 } else { 199 } else {
197 val = 0; 200 val = 0;
198 } 201 }
199 ifstate_push(&lp->current, val); 202 ifstate_push(&lp->current, val);
200 dostrfree(expr); 203 dostrfree(expr);
204
205 if (doprint) {
206 debuglog(&lp->current, "#if: %s",
207 ifstate->curtrue ? "taken" : "not taken");
208 }
201 } 209 }
202 210
203 static 211 static
204 void 212 void
205 d_ifdef(struct lineplace *lp, struct place *p2, char *line) 213 d_ifdef(struct lineplace *lp, struct place *p2, char *line)
206 { 214 {
215 bool doprint;
216
217 doprint = ifstate->curtrue;
218
207 uncomment(line); 219 uncomment(line);
208 oneword("#ifdef", p2, line); 220 oneword("#ifdef", p2, line);
209 ifstate_push(&lp->current, macro_isdefined(line)); 221 ifstate_push(&lp->current, macro_isdefined(line));
222
223 if (doprint) {
224 debuglog(&lp->current, "#ifdef %s: %s",
225 line, ifstate->curtrue ? "taken" : "not taken");
226 }
210 } 227 }
211 228
212 static 229 static
213 void 230 void
214 d_ifndef(struct lineplace *lp, struct place *p2, char *line) 231 d_ifndef(struct lineplace *lp, struct place *p2, char *line)
215 { 232 {
233 bool doprint;
234
235 doprint = ifstate->curtrue;
236
216 uncomment(line); 237 uncomment(line);
217 oneword("#ifndef", p2, line); 238 oneword("#ifndef", p2, line);
218 ifstate_push(&lp->current, !macro_isdefined(line)); 239 ifstate_push(&lp->current, !macro_isdefined(line));
240
241 if (doprint) {
242 debuglog(&lp->current, "#ifndef %s: %s",
243 line, ifstate->curtrue ? "taken" : "not taken");
244 }
219 } 245 }
220 246
221 static 247 static
222 void 248 void
223 d_elif(struct lineplace *lp, struct place *p2, char *line) 249 d_elif(struct lineplace *lp, struct place *p2, char *line)
224 { 250 {
251 bool doprint;
225 char *expr; 252 char *expr;
226 struct place p3 = *p2; 253 struct place p3 = *p2;
227 size_t oldlen; 254 size_t oldlen;
228 255
229 if (ifstate->seenelse) { 256 if (ifstate->seenelse) {
230 complain(&lp->current, "#elif after #else"); 257 complain(&lp->current, "#elif after #else");
231 complain_fail(); 258 complain_fail();
232 } 259 }
260
261 doprint = ifstate->curtrue;
233 262
234 if (ifstate->evertrue) { 263 if (ifstate->evertrue) {
235 ifstate->curtrue = false; 264 ifstate->curtrue = false;
236 } else { 265 } else {
237 expr = macroexpand(p2, line, strlen(line), true); 266 expr = macroexpand(p2, line, strlen(line), true);
243 272
244 ifstate->curtrue = eval(&p3, expr); 273 ifstate->curtrue = eval(&p3, expr);
245 ifstate->evertrue = ifstate->curtrue; 274 ifstate->evertrue = ifstate->curtrue;
246 dostrfree(expr); 275 dostrfree(expr);
247 } 276 }
277
278 if (doprint) {
279 debuglog2(&lp->current, &ifstate->startplace, "#elif: %s",
280 ifstate->curtrue ? "taken" : "not taken");
281 }
248 } 282 }
249 283
250 static 284 static
251 void 285 void
252 d_else(struct lineplace *lp, struct place *p2, char *line) 286 d_else(struct lineplace *lp, struct place *p2, char *line)
253 { 287 {
288 bool doprint;
289
254 (void)p2; 290 (void)p2;
255 (void)line; 291 (void)line;
256 292
257 if (ifstate->seenelse) { 293 if (ifstate->seenelse) {
258 complain(&lp->current, 294 complain(&lp->current,
259 "Multiple #else directives in one conditional"); 295 "Multiple #else directives in one conditional");
260 complain_fail(); 296 complain_fail();
261 } 297 }
262 298
299 doprint = ifstate->curtrue;
300
263 ifstate->curtrue = !ifstate->evertrue; 301 ifstate->curtrue = !ifstate->evertrue;
264 ifstate->evertrue = true; 302 ifstate->evertrue = true;
265 ifstate->seenelse = true; 303 ifstate->seenelse = true;
304
305 if (doprint) {
306 debuglog2(&lp->current, &ifstate->startplace, "#else: %s",
307 ifstate->curtrue ? "taken" : "not taken");
308 }
266 } 309 }
267 310
268 static 311 static
269 void 312 void
270 d_endif(struct lineplace *lp, struct place *p2, char *line) 313 d_endif(struct lineplace *lp, struct place *p2, char *line)
274 317
275 if (ifstate->prev == NULL) { 318 if (ifstate->prev == NULL) {
276 complain(&lp->current, "Unmatched #endif"); 319 complain(&lp->current, "Unmatched #endif");
277 complain_fail(); 320 complain_fail();
278 } else { 321 } else {
322 debuglog2(&lp->current, &ifstate->startplace, "#endif");
279 ifstate_pop(); 323 ifstate_pop();
280 } 324 }
281 } 325 }
282 326
283 //////////////////////////////////////////////////////////// 327 ////////////////////////////////////////////////////////////
338 382
339 p4 = *p2; 383 p4 = *p2;
340 p4.column += pos; 384 p4.column += pos;
341 385
342 if (argpos) { 386 if (argpos) {
387 debuglog(&lp->current, "Defining %s()", line);
343 macro_define_params(p2, line, &p3, 388 macro_define_params(p2, line, &p3,
344 line + argpos, &p4, 389 line + argpos, &p4,
345 line + pos); 390 line + pos);
346 } else { 391 } else {
392 debuglog(&lp->current, "Defining %s", line);
347 macro_define_plain(p2, line, &p4, line + pos); 393 macro_define_plain(p2, line, &p4, line + pos);
348 } 394 }
349 } 395 }
350 396
351 static 397 static
354 { 400 {
355 (void)lp; 401 (void)lp;
356 402
357 uncomment(line); 403 uncomment(line);
358 oneword("#undef", p2, line); 404 oneword("#undef", p2, line);
405 debuglog(&lp->current, "Undef %s", line);
359 macro_undef(line); 406 macro_undef(line);
360 } 407 }
361 408
362 //////////////////////////////////////////////////////////// 409 ////////////////////////////////////////////////////////////
363 // includes 410 // includes
369 size_t len; 416 size_t len;
370 417
371 len = strlen(line); 418 len = strlen(line);
372 if (len > 2 && line[0] == '"' && line[len-1] == '"') { 419 if (len > 2 && line[0] == '"' && line[len-1] == '"') {
373 line[len-1] = '\0'; 420 line[len-1] = '\0';
421 debuglog(p, "Entering include file \"%s\"", line+1);
374 file_readquote(p, line+1); 422 file_readquote(p, line+1);
423 debuglog(p, "Leaving include file \"%s\"", line+1);
375 line[len-1] = '"'; 424 line[len-1] = '"';
376 return true; 425 return true;
377 } 426 }
378 if (len > 2 && line[0] == '<' && line[len-1] == '>') { 427 if (len > 2 && line[0] == '<' && line[len-1] == '>') {
379 line[len-1] = '\0'; 428 line[len-1] = '\0';
429 debuglog(p, "Entering include file <%s>", line+1);
380 file_readbracket(p, line+1); 430 file_readbracket(p, line+1);
431 debuglog(p, "Leaving include file <%s>", line+1);
381 line[len-1] = '>'; 432 line[len-1] = '>';
382 return true; 433 return true;
383 } 434 }
384 return false; 435 return false;
385 } 436 }