Annotation of src/usr.bin/m4/trace.c, Revision 1.14
1.14 ! espie 1: /* $OpenBSD: trace.c,v 1.13 2006/01/20 23:10:19 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:
27: #include <stddef.h>
1.13 espie 28: #include <stdint.h>
1.1 espie 29: #include <stdio.h>
1.13 espie 30: #include <stdlib.h>
1.1 espie 31: #include "mdef.h"
32: #include "stdd.h"
33: #include "extern.h"
34:
1.12 espie 35: FILE *traceout;
1.1 espie 36:
37: #define TRACE_ARGS 1
38: #define TRACE_EXPANSION 2
39: #define TRACE_QUOTE 4
40: #define TRACE_FILENAME 8
41: #define TRACE_LINENO 16
42: #define TRACE_CONT 32
43: #define TRACE_ID 64
44: #define TRACE_NEWFILE 128 /* not implemented yet */
45: #define TRACE_INPUT 256 /* not implemented yet */
46:
1.4 millert 47: static unsigned int letter_to_flag(int);
48: static void print_header(struct input_file *);
49: static int frame_level(void);
1.1 espie 50:
1.7 espie 51:
1.10 espie 52: unsigned int trace_flags = TRACE_QUOTE | TRACE_EXPANSION;
1.1 espie 53:
54: void
1.6 espie 55: trace_file(const char *name)
1.1 espie 56: {
57:
1.12 espie 58: if (traceout && traceout != stderr)
1.1 espie 59: fclose(traceout);
60: traceout = fopen(name, "w");
61: if (!traceout)
62: err(1, "can't open %s", name);
63: }
64:
65: static unsigned int
1.6 espie 66: letter_to_flag(int c)
1.1 espie 67: {
68: switch(c) {
69: case 'a':
70: return TRACE_ARGS;
71: case 'e':
72: return TRACE_EXPANSION;
73: case 'q':
74: return TRACE_QUOTE;
75: case 'c':
76: return TRACE_CONT;
77: case 'x':
78: return TRACE_ID;
79: case 'f':
80: return TRACE_FILENAME;
81: case 'l':
82: return TRACE_LINENO;
83: case 'p':
84: return TRACE_NEWFILE;
85: case 'i':
86: return TRACE_INPUT;
87: case 't':
88: return TRACE_ALL;
89: case 'V':
90: return ~0;
91: default:
92: return 0;
93: }
94: }
95:
96: void
1.6 espie 97: set_trace_flags(const char *s)
1.1 espie 98: {
99: char mode = 0;
100: unsigned int f = 0;
101:
102: if (*s == '+' || *s == '-')
103: mode = *s++;
104: while (*s)
105: f |= letter_to_flag(*s++);
106: switch(mode) {
107: case 0:
1.10 espie 108: trace_flags = f;
1.1 espie 109: break;
110: case '+':
1.10 espie 111: trace_flags |= f;
1.1 espie 112: break;
113: case '-':
1.10 espie 114: trace_flags &= ~f;
1.1 espie 115: break;
116: }
117: }
118:
1.3 espie 119: static int
120: frame_level()
121: {
122: int level;
123: int framep;
124:
125: for (framep = fp, level = 0; framep != 0;
1.8 espie 126: level++,framep = mstack[framep-3].sfra)
1.3 espie 127: ;
128: return level;
129: }
130:
1.1 espie 131: static void
1.6 espie 132: print_header(struct input_file *inp)
1.1 espie 133: {
134: fprintf(traceout, "m4trace:");
1.10 espie 135: if (trace_flags & TRACE_FILENAME)
1.1 espie 136: fprintf(traceout, "%s:", inp->name);
1.10 espie 137: if (trace_flags & TRACE_LINENO)
1.1 espie 138: fprintf(traceout, "%lu:", inp->lineno);
1.3 espie 139: fprintf(traceout, " -%d- ", frame_level());
1.10 espie 140: if (trace_flags & TRACE_ID)
1.1 espie 141: fprintf(traceout, "id %lu: ", expansion_id);
142: }
143:
1.13 espie 144: size_t
1.6 espie 145: trace(const char *argv[], int argc, struct input_file *inp)
1.1 espie 146: {
1.12 espie 147: if (!traceout)
148: traceout = stderr;
1.1 espie 149: print_header(inp);
1.10 espie 150: if (trace_flags & TRACE_CONT) {
1.1 espie 151: fprintf(traceout, "%s ...\n", argv[1]);
152: print_header(inp);
153: }
154: fprintf(traceout, "%s", argv[1]);
1.10 espie 155: if ((trace_flags & TRACE_ARGS) && argc > 2) {
1.3 espie 156: char delim[3];
1.1 espie 157: int i;
158:
1.3 espie 159: delim[0] = LPAREN;
160: delim[1] = EOS;
1.1 espie 161: for (i = 2; i < argc; i++) {
1.3 espie 162: fprintf(traceout, "%s%s%s%s", delim,
1.10 espie 163: (trace_flags & TRACE_QUOTE) ? lquote : "",
1.1 espie 164: argv[i],
1.10 espie 165: (trace_flags & TRACE_QUOTE) ? rquote : "");
1.3 espie 166: delim[0] = COMMA;
167: delim[1] = ' ';
168: delim[2] = EOS;
1.1 espie 169: }
170: fprintf(traceout, "%c", RPAREN);
171: }
1.10 espie 172: if (trace_flags & TRACE_CONT) {
1.1 espie 173: fprintf(traceout, " -> ???\n");
174: print_header(inp);
175: fprintf(traceout, argc > 2 ? "%s(...)" : "%s", argv[1]);
176: }
1.10 espie 177: if (trace_flags & TRACE_EXPANSION)
1.1 espie 178: return buffer_mark();
179: else {
180: fprintf(traceout, "\n");
1.13 espie 181: return SIZE_MAX;
1.1 espie 182: }
183: }
184:
185: void
1.6 espie 186: finish_trace(size_t mark)
1.1 espie 187: {
188: fprintf(traceout, " -> ");
1.10 espie 189: if (trace_flags & TRACE_QUOTE)
1.1 espie 190: fprintf(traceout, "%s", lquote);
191: dump_buffer(traceout, mark);
1.10 espie 192: if (trace_flags & TRACE_QUOTE)
1.1 espie 193: fprintf(traceout, "%s", rquote);
194: fprintf(traceout, "\n");
195: }