Annotation of src/usr.bin/m4/trace.c, Revision 1.10
1.10 ! espie 1: /* $OpenBSD: trace.c,v 1.9 2003/06/30 22:10:21 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 <sys/types.h>
28: #include <stddef.h>
29: #include <stdio.h>
30: #include <err.h>
1.2 espie 31: #include <stdlib.h>
1.1 espie 32: #include "mdef.h"
33: #include "stdd.h"
34: #include "extern.h"
35:
36: FILE *traceout = stderr;
37:
38: #define TRACE_ARGS 1
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 struct t *find_trace_entry(const char *);
51: static int frame_level(void);
1.1 espie 52:
1.7 espie 53:
1.10 ! espie 54: unsigned int trace_flags = TRACE_QUOTE | TRACE_EXPANSION;
1.1 espie 55:
56: void
1.6 espie 57: trace_file(const char *name)
1.1 espie 58: {
59:
60: if (traceout != stderr)
61: fclose(traceout);
62: traceout = fopen(name, "w");
63: if (!traceout)
64: err(1, "can't open %s", name);
65: }
66:
67: static unsigned int
1.6 espie 68: letter_to_flag(int c)
1.1 espie 69: {
70: switch(c) {
71: case 'a':
72: return TRACE_ARGS;
73: case 'e':
74: return TRACE_EXPANSION;
75: case 'q':
76: return TRACE_QUOTE;
77: case 'c':
78: return TRACE_CONT;
79: case 'x':
80: return TRACE_ID;
81: case 'f':
82: return TRACE_FILENAME;
83: case 'l':
84: return TRACE_LINENO;
85: case 'p':
86: return TRACE_NEWFILE;
87: case 'i':
88: return TRACE_INPUT;
89: case 't':
90: return TRACE_ALL;
91: case 'V':
92: return ~0;
93: default:
94: return 0;
95: }
96: }
97:
98: void
1.6 espie 99: set_trace_flags(const char *s)
1.1 espie 100: {
101: char mode = 0;
102: unsigned int f = 0;
103:
104: if (*s == '+' || *s == '-')
105: mode = *s++;
106: while (*s)
107: f |= letter_to_flag(*s++);
108: switch(mode) {
109: case 0:
1.10 ! espie 110: trace_flags = f;
1.1 espie 111: break;
112: case '+':
1.10 ! espie 113: trace_flags |= f;
1.1 espie 114: break;
115: case '-':
1.10 ! espie 116: trace_flags &= ~f;
1.1 espie 117: break;
118: }
119: }
120:
1.3 espie 121: static int
122: frame_level()
123: {
124: int level;
125: int framep;
126:
127: for (framep = fp, level = 0; framep != 0;
1.8 espie 128: level++,framep = mstack[framep-3].sfra)
1.3 espie 129: ;
130: return level;
131: }
132:
1.1 espie 133: static void
1.6 espie 134: print_header(struct input_file *inp)
1.1 espie 135: {
136: fprintf(traceout, "m4trace:");
1.10 ! espie 137: if (trace_flags & TRACE_FILENAME)
1.1 espie 138: fprintf(traceout, "%s:", inp->name);
1.10 ! espie 139: if (trace_flags & TRACE_LINENO)
1.1 espie 140: fprintf(traceout, "%lu:", inp->lineno);
1.3 espie 141: fprintf(traceout, " -%d- ", frame_level());
1.10 ! espie 142: if (trace_flags & TRACE_ID)
1.1 espie 143: fprintf(traceout, "id %lu: ", expansion_id);
144: }
145:
146: ssize_t
1.6 espie 147: trace(const char *argv[], int argc, struct input_file *inp)
1.1 espie 148: {
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");
181: return -1;
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: }