1.fp 5 CW
2.de Af
3.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
4.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
5..
6.de aF
7.ie \\$3 .ft \\$1
8.el \{\
9.ds ;G \&
10.nr ;G \\n(.f
11.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
12\\*(;G
13.ft \\n(;G \}
14..
15.de L
16.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
17..
18.de LR
19.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
20..
21.de RL
22.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
23..
24.de EX		\" start example
25.ta 1i 2i 3i 4i 5i 6i
26.PP
27.RS 
28.PD 0
29.ft 5
30.nf
31..
32.de EE		\" end example
33.fi
34.ft
35.PD
36.RE
37.PP
38..
39.TH ERROR 3
40.SH NAME
41error \- error and debug trace message formatter
42.SH SYNOPSIS
43.EX
44#include <error.h>
45
46Error_info_t error_info;
47
48void         error(int \fIlevel\fP, ...);
49void         errorv(const char* \fIlibrary\fP, int \fIlevel\fP, va_alist \fIargs\fP);
50void         liberror(const char* \fIlibrary\fP, int \fIlevel\fP, ...);
51
52#include <debug.h>
53
54debug(\fIstatement\fP)
55message((int \fIlevel\fP, ...))
56libmessage((const char* \fIlibrary\fI, int \fIlevel\fP, ...))
57.EE
58.SH DESCRIPTION
59.L error
60is the error and debug trace message formatter.
61.I level
62is the severity level.
63Messages with
64.I "level < error_info.trace"
65are suppressed.
66.I error_info.trace
67is initially
68.LR 0 .
69The remaining arguments are passed on to
70.LR printf .
71A
72.I newline
73is appended to the message text, so none should appear in the
74.L printf
75format.
76If 
77.I error_info.id
78is not
79.L 0
80then messages with
81.I "level > 0"
82are prefixed by
83.IR error_info.id: .
84.PP
85Before the message text is output to standard error
86it is passed to the function
87.LR "char* ERROR_translate(const char* \fItext\fP, int \fIflag\fP)" .
88By default
89.L ERROR_translate
90returns the
91.L text
92argument, but on some systems it may do language translation via lookup
93on the original source text.
94.RL ( error
95calls 
96.L ERROR_translate
97with a 0
98.L flag
99argument).
100.PP
101.I level
102may be one of:
103.TP
104.B <0
105Negative values are for debug tracing.
106Debug messages are prefixed with
107.BI debug level.
108If
109.I "errno != error_info.last_errno"
110then 
111.I error_info.last_errno
112is set to
113.I errno
114and the error text for errno is appended to the message.
115.TP
116.B "ERROR_INFO [0]"
117Information only; no prefixes are added to the message.
118.TP
119.B "ERROR_WARNING [1]"
120.L "warning:"
121is added after
122.L error_info.id
123and
124.I error_info.warnings
125is incremented.
126.TP
127.I "ERROR_ERROR [2]"
128(soft error)
129.I error_info.errors
130is incremented.
131.TP
132.B ">= ERROR_FATAL [3]"
133(hard error)
134.I error_info.errors
135is incremented and
136.L exit(\fIlevel\fP\-2)
137is called after the message is emitted.
138.TP
139.B "ERROR_PANIC [77]"
140(unrecoverable internal error)
141.L "panic:"
142is added after
143.IR error_info.id .
144.PP
145The following may be inclusive-or'd into
146.I level
147for alternate behavior:
148.TP
149.L ERROR_SYSTEM
150The error text for
151.I errno
152is appended to the message.
153.TP
154.L ERROR_OUTPUT
155The next argument is the file descriptor where the error message
156should be emitted.
157.TP
158.L ERROR_SOURCE
159Then next two arguments are a file name and line number that are added
160to the message after
161.IR error_info.id .
162.TP
163.L ERROR_USAGE
164A usage message is emitted.
165.TP
166.L ERROR_PROMPT
167The trailing 
168.I newline
169is suppressed.
170.TP
171.L ERROR_NOID
172The
173.I error_info.id
174prefix is suppressed.
175.TP
176.L ERROR_LIBRARY
177The message is from a library routine.
178.SH ENVIRONMENT
179The elements of the global struct
180.I error_info
181control error output and actions.
182Parts of 
183.I error_info
184can be initialized from the
185.L ERROR_OPTIONS
186environment variable.
187.L ERROR_OPTIONS
188contains space separated
189.IR name [ =value ]
190options, described below.
191.TP
192.I "int core"
193If
194.I "error_info.core != 0"
195then 
196.I "level >= error_info.core"
197generates a core dump.
198Initialized by
199.EX
200ERROR_OPTIONS="core=\fIlevel\fP"
201.EE
202where 
203.I level
204can be a number or one of
205.LR error ,
206.LR fatal ,
207or
208.LR panic .
209.I error_info.core
210is a handy way to get a stack trace at the exact point of error.
211.TP
212.I "int error_info.trace"
213If
214.I "error_info.trace != 0"
215and
216.I "level < error_info.trace"
217then the error message text is suppressed.
218.L exit()
219may still be called if appropriate for
220.IR level .
221Initialized by
222.EX
223ERROR_OPTIONS="trace=\fIlevel\fP"
224.EE
225where
226.I error_info.trace
227is set to the negative of
228.IR level .
229.PP
230Library error messages, suppressed by default, are enabled by
231.EX
232ERROR_OPTIONS="library"
233.EE
234The system
235.I errno
236message text can be forced for each message by
237.EX
238ERROR_OPTIONS="system"
239.EE
240.SH "EXTENDED DESCRIPTION"
241.L "<debug.h>"
242provides debugging message macros when
243.L DEBUG
244or
245.L _TRACE_
246are defined
247.RL ( _TRACE_
248is defined by
249.I makerules
250when 
251.L CCFLAGS
252contains
253.LR \-g ).
254All of the macros expand to nothing when both
255.L DEBUG
256and
257.L _TRACE_
258are not defined.
259Otherwise
260.L debug
261expands its arg and
262.L libmessage
263and
264.L message
265call
266.L liberror
267and 
268.L error
269respectively if
270.IR "error_info.trace<0" .
271Notice that
272.L libmessage
273and
274.L message
275are macro hacks that require double parentheses ((...)) around the
276arguments.
277.SH EXAMPLE
278To enable debugging message level -3, library messages, and system
279.I errno
280text for all commands:
281.EX
282export ERROR_OPTIONS="trace=3 library system"
283.EE
284