[BACK]Return to trace.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / m4

Annotation of src/usr.bin/m4/trace.c, Revision 1.4

1.4     ! millert     1: /* $OpenBSD: trace.c,v 1.3 2001/09/29 15:47:18 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: int traced_macros = 0;
                     39:
                     40: #define TRACE_ARGS     1
                     41: #define TRACE_EXPANSION 2
                     42: #define TRACE_QUOTE    4
                     43: #define TRACE_FILENAME 8
                     44: #define TRACE_LINENO   16
                     45: #define TRACE_CONT     32
                     46: #define TRACE_ID       64
                     47: #define TRACE_NEWFILE  128     /* not implemented yet */
                     48: #define TRACE_INPUT    256     /* not implemented yet */
                     49: #define TRACE_ALL      512
                     50:
1.2       espie      51: static struct t {
                     52:        struct t *next;
                     53:        char     *name;
                     54:        int       on;
                     55: } *l;
1.1       espie      56:
1.4     ! millert    57: static unsigned int letter_to_flag(int);
        !            58: static void print_header(struct input_file *);
        !            59: static struct t *find_trace_entry(const char *);
        !            60: static int frame_level(void);
1.1       espie      61:
                     62: static unsigned int flags = TRACE_QUOTE | TRACE_EXPANSION;
                     63:
1.2       espie      64: static struct t *
                     65: find_trace_entry(name)
                     66:        const char *name;
                     67: {
                     68:        struct t *n;
                     69:
                     70:        for (n = l; n != NULL; n = n->next)
                     71:                if (STREQ(n->name, name))
                     72:                        return n;
                     73:        return NULL;
                     74: }
                     75:
1.1       espie      76:
                     77: void
1.2       espie      78: mark_traced(name, on)
1.1       espie      79:        const char *name;
1.2       espie      80:        int on;
1.1       espie      81: {
1.2       espie      82:        struct t *n, *n2;
1.1       espie      83:
                     84:        traced_macros = 1;
1.2       espie      85:
                     86:        if (name == NULL) {
                     87:                if (on)
                     88:                        flags |= TRACE_ALL;
                     89:                else {
                     90:                        flags &= ~TRACE_ALL;
                     91:                        traced_macros = 0;
                     92:                }
                     93:                for (n = l; n != NULL; n = n2) {
                     94:                        n2 = n->next;
                     95:                        free(n->name);
                     96:                        free(n);
                     97:                }
                     98:                l = NULL;
                     99:        } else {
                    100:            n = find_trace_entry(name);
                    101:            if (n == NULL) {
1.1       espie     102:        n = xalloc(sizeof(struct t));
                    103:        n->name = xstrdup(name);
                    104:        n->next = l;
                    105:        l = n;
1.2       espie     106:            }
                    107:            n->on = on;
                    108:        }
1.1       espie     109: }
                    110:
                    111: int
                    112: is_traced(name)
                    113:        const char *name;
                    114: {
                    115:        struct t *n;
                    116:
                    117:        for (n = l; n != NULL; n = n->next)
                    118:                if (STREQ(n->name, name))
1.2       espie     119:                        return n->on;
                    120:        return (flags & TRACE_ALL) ? 1 : 0;
1.1       espie     121: }
                    122:
                    123: void
                    124: trace_file(name)
                    125:        const char *name;
                    126: {
                    127:
                    128:        if (traceout != stderr)
                    129:                fclose(traceout);
                    130:        traceout = fopen(name, "w");
                    131:        if (!traceout)
                    132:                err(1, "can't open %s", name);
                    133: }
                    134:
                    135: static unsigned int
                    136: letter_to_flag(c)
                    137:        int c;
                    138: {
                    139:        switch(c) {
                    140:        case 'a':
                    141:                return TRACE_ARGS;
                    142:        case 'e':
                    143:                return TRACE_EXPANSION;
                    144:        case 'q':
                    145:                return TRACE_QUOTE;
                    146:        case 'c':
                    147:                return TRACE_CONT;
                    148:        case 'x':
                    149:                return TRACE_ID;
                    150:        case 'f':
                    151:                return TRACE_FILENAME;
                    152:        case 'l':
                    153:                return TRACE_LINENO;
                    154:        case 'p':
                    155:                return TRACE_NEWFILE;
                    156:        case 'i':
                    157:                return TRACE_INPUT;
                    158:        case 't':
                    159:                return TRACE_ALL;
                    160:        case 'V':
                    161:                return ~0;
                    162:        default:
                    163:                return 0;
                    164:        }
                    165: }
                    166:
                    167: void
                    168: set_trace_flags(s)
                    169:        const char *s;
                    170: {
                    171:        char mode = 0;
                    172:        unsigned int f = 0;
                    173:
                    174:        traced_macros = 1;
                    175:
                    176:        if (*s == '+' || *s == '-')
                    177:                mode = *s++;
                    178:        while (*s)
                    179:                f |= letter_to_flag(*s++);
                    180:        switch(mode) {
                    181:        case 0:
                    182:                flags = f;
                    183:                break;
                    184:        case '+':
                    185:                flags |= f;
                    186:                break;
                    187:        case '-':
                    188:                flags &= ~f;
                    189:                break;
                    190:        }
                    191: }
                    192:
1.3       espie     193: static int
                    194: frame_level()
                    195: {
                    196:        int level;
                    197:        int framep;
                    198:
                    199:        for (framep = fp, level = 0; framep != 0;
                    200:                level++,framep = mstack[framep-2].sfra)
                    201:                ;
                    202:        return level;
                    203: }
                    204:
1.1       espie     205: static void
                    206: print_header(inp)
                    207:        struct input_file *inp;
                    208: {
                    209:        fprintf(traceout, "m4trace:");
                    210:        if (flags & TRACE_FILENAME)
                    211:                fprintf(traceout, "%s:", inp->name);
                    212:        if (flags & TRACE_LINENO)
                    213:                fprintf(traceout, "%lu:", inp->lineno);
1.3       espie     214:        fprintf(traceout, " -%d- ", frame_level());
1.1       espie     215:        if (flags & TRACE_ID)
                    216:                fprintf(traceout, "id %lu: ", expansion_id);
                    217: }
                    218:
                    219: ssize_t
                    220: trace(argv, argc, inp)
                    221:        const char **argv;
                    222:        int argc;
                    223:        struct input_file *inp;
                    224: {
                    225:        print_header(inp);
                    226:        if (flags & TRACE_CONT) {
                    227:                fprintf(traceout, "%s ...\n", argv[1]);
                    228:                print_header(inp);
                    229:        }
                    230:        fprintf(traceout, "%s", argv[1]);
                    231:        if ((flags & TRACE_ARGS) && argc > 2) {
1.3       espie     232:                char delim[3];
1.1       espie     233:                int i;
                    234:
1.3       espie     235:                delim[0] = LPAREN;
                    236:                delim[1] = EOS;
1.1       espie     237:                for (i = 2; i < argc; i++) {
1.3       espie     238:                        fprintf(traceout, "%s%s%s%s", delim,
1.1       espie     239:                            (flags & TRACE_QUOTE) ? lquote : "",
                    240:                            argv[i],
                    241:                            (flags & TRACE_QUOTE) ? rquote : "");
1.3       espie     242:                        delim[0] = COMMA;
                    243:                        delim[1] = ' ';
                    244:                        delim[2] = EOS;
1.1       espie     245:                }
                    246:                fprintf(traceout, "%c", RPAREN);
                    247:        }
                    248:        if (flags & TRACE_CONT) {
                    249:                fprintf(traceout, " -> ???\n");
                    250:                print_header(inp);
                    251:                fprintf(traceout, argc > 2 ? "%s(...)" : "%s", argv[1]);
                    252:        }
                    253:        if (flags & TRACE_EXPANSION)
                    254:                return buffer_mark();
                    255:        else {
                    256:                fprintf(traceout, "\n");
                    257:                return -1;
                    258:        }
                    259: }
                    260:
                    261: void
                    262: finish_trace(mark)
                    263: size_t mark;
                    264: {
                    265:        fprintf(traceout, " -> ");
                    266:        if (flags & TRACE_QUOTE)
                    267:                fprintf(traceout, "%s", lquote);
                    268:        dump_buffer(traceout, mark);
                    269:        if (flags & TRACE_QUOTE)
                    270:                fprintf(traceout, "%s", rquote);
                    271:        fprintf(traceout, "\n");
                    272: }