Annotation of src/usr.bin/m4/trace.c, Revision 1.16
1.16 ! marco 1: /* $OpenBSD: trace.c,v 1.15 2006/03/24 08:03:44 espie Exp $ */
1.1 espie 2: /*
3: * Copyright (c) 2001 Marc Espie.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
15: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
18: * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
1.15 espie 27: #include <err.h>
1.1 espie 28: #include <stddef.h>
1.13 espie 29: #include <stdint.h>
1.1 espie 30: #include <stdio.h>
1.13 espie 31: #include <stdlib.h>
1.1 espie 32: #include "mdef.h"
33: #include "stdd.h"
34: #include "extern.h"
35:
1.12 espie 36: FILE *traceout;
1.1 espie 37:
1.16 ! marco 38: #define TRACE_ARGS 1
1.1 espie 39: #define TRACE_EXPANSION 2
40: #define TRACE_QUOTE 4
41: #define TRACE_FILENAME 8
42: #define TRACE_LINENO 16
43: #define TRACE_CONT 32
44: #define TRACE_ID 64
45: #define TRACE_NEWFILE 128 /* not implemented yet */
46: #define TRACE_INPUT 256 /* not implemented yet */
47:
1.4 millert 48: static unsigned int letter_to_flag(int);
49: static void print_header(struct input_file *);
50: static int frame_level(void);
1.1 espie 51:
1.7 espie 52:
1.10 espie 53: unsigned int trace_flags = TRACE_QUOTE | TRACE_EXPANSION;
1.1 espie 54:
55: void
1.6 espie 56: trace_file(const char *name)
1.1 espie 57: {
58:
1.12 espie 59: if (traceout && traceout != stderr)
1.1 espie 60: fclose(traceout);
61: traceout = fopen(name, "w");
62: if (!traceout)
63: err(1, "can't open %s", name);
64: }
65:
66: static unsigned int
1.6 espie 67: letter_to_flag(int c)
1.1 espie 68: {
69: switch(c) {
70: case 'a':
71: return TRACE_ARGS;
72: case 'e':
73: return TRACE_EXPANSION;
74: case 'q':
75: return TRACE_QUOTE;
76: case 'c':
77: return TRACE_CONT;
78: case 'x':
79: return TRACE_ID;
80: case 'f':
81: return TRACE_FILENAME;
82: case 'l':
83: return TRACE_LINENO;
84: case 'p':
85: return TRACE_NEWFILE;
86: case 'i':
87: return TRACE_INPUT;
88: case 't':
89: return TRACE_ALL;
90: case 'V':
91: return ~0;
92: default:
93: return 0;
94: }
95: }
96:
97: void
1.6 espie 98: set_trace_flags(const char *s)
1.1 espie 99: {
100: char mode = 0;
101: unsigned int f = 0;
102:
103: if (*s == '+' || *s == '-')
104: mode = *s++;
105: while (*s)
106: f |= letter_to_flag(*s++);
107: switch(mode) {
108: case 0:
1.10 espie 109: trace_flags = f;
1.1 espie 110: break;
111: case '+':
1.10 espie 112: trace_flags |= f;
1.1 espie 113: break;
114: case '-':
1.10 espie 115: trace_flags &= ~f;
1.1 espie 116: break;
117: }
118: }
119:
1.3 espie 120: static int
121: frame_level()
122: {
123: int level;
124: int framep;
125:
1.16 ! marco 126: for (framep = fp, level = 0; framep != 0;
1.8 espie 127: level++,framep = mstack[framep-3].sfra)
1.3 espie 128: ;
129: return level;
130: }
131:
1.1 espie 132: static void
1.6 espie 133: print_header(struct input_file *inp)
1.1 espie 134: {
135: fprintf(traceout, "m4trace:");
1.10 espie 136: if (trace_flags & TRACE_FILENAME)
1.1 espie 137: fprintf(traceout, "%s:", inp->name);
1.10 espie 138: if (trace_flags & TRACE_LINENO)
1.1 espie 139: fprintf(traceout, "%lu:", inp->lineno);
1.3 espie 140: fprintf(traceout, " -%d- ", frame_level());
1.10 espie 141: if (trace_flags & TRACE_ID)
1.1 espie 142: fprintf(traceout, "id %lu: ", expansion_id);
143: }
144:
1.16 ! marco 145: size_t
1.6 espie 146: trace(const char *argv[], int argc, struct input_file *inp)
1.1 espie 147: {
1.12 espie 148: if (!traceout)
149: traceout = stderr;
1.1 espie 150: print_header(inp);
1.10 espie 151: if (trace_flags & TRACE_CONT) {
1.1 espie 152: fprintf(traceout, "%s ...\n", argv[1]);
153: print_header(inp);
154: }
155: fprintf(traceout, "%s", argv[1]);
1.10 espie 156: if ((trace_flags & TRACE_ARGS) && argc > 2) {
1.3 espie 157: char delim[3];
1.1 espie 158: int i;
159:
1.3 espie 160: delim[0] = LPAREN;
161: delim[1] = EOS;
1.1 espie 162: for (i = 2; i < argc; i++) {
1.16 ! marco 163: fprintf(traceout, "%s%s%s%s", delim,
! 164: (trace_flags & TRACE_QUOTE) ? lquote : "",
! 165: argv[i],
1.10 espie 166: (trace_flags & TRACE_QUOTE) ? rquote : "");
1.3 espie 167: delim[0] = COMMA;
168: delim[1] = ' ';
169: delim[2] = EOS;
1.1 espie 170: }
171: fprintf(traceout, "%c", RPAREN);
172: }
1.10 espie 173: if (trace_flags & TRACE_CONT) {
1.1 espie 174: fprintf(traceout, " -> ???\n");
175: print_header(inp);
176: fprintf(traceout, argc > 2 ? "%s(...)" : "%s", argv[1]);
177: }
1.10 espie 178: if (trace_flags & TRACE_EXPANSION)
1.1 espie 179: return buffer_mark();
180: else {
181: fprintf(traceout, "\n");
1.13 espie 182: return SIZE_MAX;
1.1 espie 183: }
184: }
185:
1.16 ! marco 186: void
1.6 espie 187: finish_trace(size_t mark)
1.1 espie 188: {
189: fprintf(traceout, " -> ");
1.10 espie 190: if (trace_flags & TRACE_QUOTE)
1.1 espie 191: fprintf(traceout, "%s", lquote);
192: dump_buffer(traceout, mark);
1.10 espie 193: if (trace_flags & TRACE_QUOTE)
1.1 espie 194: fprintf(traceout, "%s", rquote);
195: fprintf(traceout, "\n");
196: }