File: error.c

package info (click to toggle)
tcng 10b-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,632 kB
  • ctags: 2,515
  • sloc: ansic: 19,038; pascal: 4,640; yacc: 2,619; sh: 1,908; perl: 1,546; lex: 772; makefile: 755
file content (135 lines) | stat: -rw-r--r-- 2,514 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * error.c - Error reporting functions
 *
 * Written 2001,2002 by Werner Almesberger
 * Copyright 2001 EPFL-ICA
 * Copyright 2001,2002 Bivio Networks, Network Robots, Werner Almesberger
 */


#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <execinfo.h>

#include <u128.h>
#include <addr.h>

#include "config.h"
#include "error.h"
#include "registry.h"


/* ----- Provide error handlers for library functions ---------------------- */


void u128_error_hook(const char *msg)
{
    error(msg);
}


void addr_error_hook(const char *msg)
{
    yyerror(msg);
}


/* ----- Debugging messages with implict indentation ----------------------- */


static int stack_zero; /* minimum stack depth */


static int backtrace_len(void)
{
    void *dummy[MAX_DEBUG_DEPTH];

    return backtrace(dummy,MAX_DEBUG_DEPTH);
}


static void vdebugf(const char *msg,va_list ap)
{
    int depth,i;

    depth = backtrace_len(); /* auto-calibrate */
    if (!stack_zero || depth < stack_zero) stack_zero = depth;
    for (i = depth-stack_zero; i; i--) putchar(' ');
    vprintf(msg,ap);
    putchar('\n');
}


void debugf(const char *msg,...)
{
    va_list ap;

    if (!debug) return;
    va_start(ap,msg);
    vdebugf(msg,ap);
    va_end(ap);
}


void debugf2(const char *msg,...)
{
    va_list ap;

    if (debug < 2) return;
    va_start(ap,msg);
    vdebugf(msg,ap);
    va_end(ap);
}


/* ----- Fine-grained warning configuration -------------------------------- */


int warn_truncate = 0; /* see config.h for description */
int warn_unused = 1;
int warn_expensive = 0;
int warn_exp_post_opt = 0;
int warn_exp_error = 0;
int warn_redefine = 0;
int warn_explicit = 1;
int warn_const_pfx = 0;


int set_warn_switch(const char *arg,int lock)
{
    static REGISTRY warn_switches;
    static int warn_switches_initialized = 0;
    static const char *warn_switch_names[] = {
	"truncate",
	"unused",
	"expensive",
	"exppostopt",
	"experror",
	"redefine",
	"explicit",
	"constpfx",
	NULL
    };
    static int *warn_switch_flags[] = {
	&warn_truncate,
	&warn_unused,
	&warn_expensive,
	&warn_exp_post_opt,
	&warn_exp_error,
	&warn_redefine,
	&warn_explicit,
	&warn_const_pfx,
	NULL
    };

    if (!warn_switches_initialized) {
	registry_open(&warn_switches,warn_switch_names,warn_switch_flags);
	warn_switches_initialized = 1;
    }
    if (registry_set_no(&warn_switches,arg)) return 0;
    if (lock && registry_lock(&warn_switches,strncmp(arg,"no",2) ? arg : arg+2))
	abort();
    return 1;
}