[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.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: }