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

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