Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/3d/error.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1989-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Eduardo Krell <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
/*
25
* Glenn Fowler
26
* AT&T Research
27
*
28
* error and message formatter
29
*
30
* level is the error level
31
* level >= error_info.core!=0 dumps core
32
* level >= ERROR_FATAL calls error_info.exit
33
* level < 0 is for debug tracing
34
*
35
* NOTE: non-sfio version just for 3d
36
*/
37
38
#include "3d.h"
39
40
#if DEBUG
41
42
static ssize_t
43
fs3d_write(int fd, const void* buf, size_t n)
44
{
45
return(WRITE(fd, buf, n));
46
}
47
48
#undef error_info
49
#define error_info _error_info_
50
51
Error_info_t _error_info_ = { 2, exit, fs3d_write };
52
Error_info_t* _error_infop_ = &_error_info_;
53
Error_info_t* _error_data_ = &_error_info_;
54
55
/*
56
* print a name, converting unprintable chars
57
*/
58
59
static void
60
print(char** buf, char* end, register char* name, char* delim)
61
{
62
register char* s = *buf;
63
register char* e = end;
64
register int c;
65
66
while (c = *name++)
67
{
68
if (c & 0200)
69
{
70
c &= 0177;
71
if (s >= e) break;
72
*s++ = '?';
73
}
74
if (c < ' ')
75
{
76
c += 'A' - 1;
77
if (s >= e) break;
78
*s++ = '^';
79
}
80
if (s >= e) break;
81
*s++ = c;
82
}
83
while (*delim)
84
{
85
if (s >= e) break;
86
*s++ = *delim++;
87
}
88
*buf = s;
89
}
90
91
void
92
errorv(const char* lib, int level, va_list ap)
93
{
94
register int n;
95
int fd;
96
int flags;
97
char* b;
98
char* e;
99
char* format;
100
char buf[4096];
101
102
int line;
103
char* file;
104
105
static int intercepted;
106
107
if (intercepted++)
108
{
109
intercepted--;
110
return;
111
}
112
if (level > 0)
113
{
114
flags = level & ~ERROR_LEVEL;
115
level &= ERROR_LEVEL;
116
}
117
else flags = 0;
118
if ((fd = fsfd(&state.fs[FS_option])) <= 0 || level < error_info.trace || lib && (error_info.clear & ERROR_LIBRARY) || level < 0 && error_info.mask && !(error_info.mask & (1<<(-level - 1))))
119
{
120
if (level >= ERROR_FATAL) (*error_info.exit)(level - 1);
121
intercepted--;
122
return;
123
}
124
if (error_info.trace < 0) flags |= ERROR_LIBRARY|ERROR_SYSTEM;
125
flags |= error_info.set;
126
flags &= ~error_info.clear;
127
if (!lib) flags &= ~ERROR_LIBRARY;
128
e = (b = buf) + elementsof(buf) - 1;
129
file = error_info.id;
130
if (flags & ERROR_USAGE)
131
{
132
bprintf(&b, e, (flags & ERROR_NOID) ? " " : "Usage: ");
133
if (file) print(&b, e, file, " ");
134
}
135
else if (level && !(flags & ERROR_NOID))
136
{
137
if (file) print(&b, e, file, (flags & ERROR_LIBRARY) ? " " : ": ");
138
if (flags & ERROR_LIBRARY)
139
bprintf(&b, e, "[%s library]: ", lib);
140
}
141
if (level > 0 && error_info.line > 0)
142
{
143
if (error_info.file && *error_info.file)
144
bprintf(&b, e, "\"%s\", ", error_info.file);
145
bprintf(&b, e, "line %d: ", error_info.line);
146
}
147
switch (level)
148
{
149
case 0:
150
break;
151
case ERROR_WARNING:
152
error_info.warnings++;
153
bprintf(&b, e, "warning: ");
154
break;
155
case ERROR_PANIC:
156
error_info.errors++;
157
bprintf(&b, e, "panic: ");
158
break;
159
default:
160
if (level < 0)
161
{
162
if (error_info.trace < -1) bprintf(&b, e, "debug%d:%s", level, level > -10 ? " " : "");
163
else bprintf(&b, e, "debug: ");
164
for (n = 0; n < error_info.indent; n++)
165
{
166
*b++ = ' ';
167
*b++ = ' ';
168
}
169
}
170
else error_info.errors++;
171
break;
172
}
173
if (flags & ERROR_OUTPUT) fd = va_arg(ap, int);
174
if (flags & ERROR_SOURCE)
175
{
176
/*
177
* source ([version], file, line) message
178
*/
179
180
file = va_arg(ap, char*);
181
line = va_arg(ap, int);
182
if (error_info.version) bprintf(&b, e, "(%s: %s, line %d) ", error_info.version, file, line);
183
else bprintf(&b, e, "(%s, line %d) ", file, line);
184
}
185
format = va_arg(ap, char*);
186
bvprintf(&b, e, format, ap);
187
if (!(flags & ERROR_PROMPT))
188
{
189
if ((flags & ERROR_SYSTEM) && errno && errno != error_info.last_errno)
190
{
191
n = state.in_2d;
192
state.in_2d = 1;
193
bprintf(&b, e, " [%s]", fmterror(errno));
194
state.in_2d = n;
195
if (error_info.set & ERROR_SYSTEM) errno = 0;
196
error_info.last_errno = (level >= 0) ? 0 : errno;
197
}
198
*b++ = '\n';
199
}
200
*b = 0;
201
if (error_info.write) (*error_info.write)(fd, buf, b - buf);
202
if (level >= error_info.core && error_info.core)
203
{
204
signal(SIGQUIT, SIG_DFL);
205
kill(getpid(), SIGQUIT);
206
pause();
207
}
208
if (level >= ERROR_FATAL) (*error_info.exit)(level - ERROR_FATAL + 1);
209
intercepted--;
210
}
211
212
void
213
error(int level, ...)
214
{
215
va_list ap;
216
217
va_start(ap, level);
218
errorv(NiL, level, ap);
219
va_end(ap);
220
}
221
222
int
223
errormsg(const char* dictionary, int level, ...)
224
{
225
va_list ap;
226
227
va_start(ap, level);
228
errorv(dictionary, level, ap);
229
va_end(ap);
230
return 0;
231
}
232
233
int
234
errorf(void* handle, void* discipline, int level, ...)
235
{
236
va_list ap;
237
238
va_start(ap, level);
239
errorv(discipline ? *((char**)handle) : (char*)handle, (discipline || level < 0) ? level : (level | ERROR_LIBRARY), ap);
240
va_end(ap);
241
return 0;
242
}
243
244
#else
245
246
NoN(error)
247
248
#endif
249
250