[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.6

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