Annotation of src/usr.bin/mandoc/mandoc_msg.c, Revision 1.7
1.7 ! schwarze 1: /* $OpenBSD: mandoc_msg.c,v 1.6 2019/07/14 18:14:27 schwarze Exp $ */
1.1 schwarze 2: /*
3: * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.7 ! schwarze 4: * Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18: #include <stdarg.h>
19: #include <stdio.h>
20: #include <stdlib.h>
21:
22: #include "mandoc.h"
23:
24: static const enum mandocerr lowest_type[MANDOCLEVEL_MAX] = {
25: MANDOCERR_OK,
26: MANDOCERR_OK,
27: MANDOCERR_WARNING,
28: MANDOCERR_ERROR,
29: MANDOCERR_UNSUPP,
1.5 schwarze 30: MANDOCERR_BADARG,
31: MANDOCERR_SYSERR
1.1 schwarze 32: };
33:
34: static const char *const level_name[MANDOCLEVEL_MAX] = {
35: "SUCCESS",
36: "STYLE",
37: "WARNING",
38: "ERROR",
39: "UNSUPP",
40: "BADARG",
41: "SYSERR"
42: };
43:
44: static const char *const type_message[MANDOCERR_MAX] = {
45: "ok",
46:
47: "base system convention",
48:
49: "Mdocdate found",
50: "Mdocdate missing",
51: "unknown architecture",
52: "operating system explicitly specified",
53: "RCS id missing",
54: "referenced manual not found",
55:
56: "generic style suggestion",
57:
58: "legacy man(7) date format",
59: "normalizing date format to",
60: "lower case character in document title",
61: "duplicate RCS id",
62: "possible typo in section name",
63: "unterminated quoted argument",
64: "useless macro",
65: "consider using OS macro",
66: "errnos out of order",
67: "duplicate errno",
68: "trailing delimiter",
69: "no blank before trailing delimiter",
70: "fill mode already enabled, skipping",
71: "fill mode already disabled, skipping",
72: "verbatim \"--\", maybe consider using \\(em",
73: "function name without markup",
74: "whitespace at end of input line",
75: "bad comment style",
76:
77: "generic warning",
78:
79: /* related to the prologue */
80: "missing manual title, using UNTITLED",
81: "missing manual title, using \"\"",
82: "missing manual section, using \"\"",
83: "unknown manual section",
1.7 ! schwarze 84: "missing date, using \"\"",
1.1 schwarze 85: "cannot parse date, using it verbatim",
86: "date in the future, using it anyway",
87: "missing Os macro, using \"\"",
88: "late prologue macro",
89: "prologue macros out of order",
90:
91: /* related to document structure */
92: ".so is fragile, better use ln(1)",
93: "no document body",
94: "content before first section header",
95: "first section is not \"NAME\"",
96: "NAME section without Nm before Nd",
97: "NAME section without description",
98: "description not at the end of NAME",
99: "bad NAME section content",
100: "missing comma before name",
101: "missing description line, using \"\"",
102: "description line outside NAME section",
103: "sections out of conventional order",
104: "duplicate section title",
105: "unexpected section",
106: "cross reference to self",
107: "unusual Xr order",
108: "unusual Xr punctuation",
109: "AUTHORS section without An macro",
110:
111: /* related to macros and nesting */
112: "obsolete macro",
113: "macro neither callable nor escaped",
114: "skipping paragraph macro",
115: "moving paragraph macro out of list",
116: "skipping no-space macro",
117: "blocks badly nested",
118: "nested displays are not portable",
119: "moving content out of list",
120: "first macro on line",
121: "line scope broken",
122: "skipping blank line in line scope",
123:
124: /* related to missing macro arguments */
125: "skipping empty request",
126: "conditional request controls empty scope",
127: "skipping empty macro",
128: "empty block",
129: "empty argument, using 0n",
130: "missing display type, using -ragged",
131: "list type is not the first argument",
132: "missing -width in -tag list, using 6n",
133: "missing utility name, using \"\"",
134: "missing function name, using \"\"",
135: "empty head in list item",
136: "empty list item",
137: "missing argument, using next line",
138: "missing font type, using \\fR",
139: "unknown font type, using \\fR",
140: "nothing follows prefix",
141: "empty reference block",
142: "missing section argument",
143: "missing -std argument, adding it",
144: "missing option string, using \"\"",
145: "missing resource identifier, using \"\"",
146: "missing eqn box, using \"\"",
147:
148: /* related to bad macro arguments */
149: "duplicate argument",
150: "skipping duplicate argument",
151: "skipping duplicate display type",
152: "skipping duplicate list type",
153: "skipping -width argument",
154: "wrong number of cells",
155: "unknown AT&T UNIX version",
156: "comma in function argument",
157: "parenthesis in function name",
158: "unknown library name",
159: "invalid content in Rs block",
160: "invalid Boolean argument",
161: "argument contains two font escapes",
162: "unknown font, skipping request",
163: "odd number of characters in request",
164:
165: /* related to plain text */
166: "blank line in fill mode, using .sp",
167: "tab in filled text",
168: "new sentence, new line",
169: "invalid escape sequence",
1.3 schwarze 170: "undefined escape, printing literally",
1.1 schwarze 171: "undefined string, using \"\"",
172:
173: /* related to tables */
174: "tbl line starts with span",
175: "tbl column starts with span",
176: "skipping vertical bar in tbl layout",
177:
178: "generic error",
179:
180: /* related to tables */
181: "non-alphabetic character in tbl options",
182: "skipping unknown tbl option",
183: "missing tbl option argument",
184: "wrong tbl option argument size",
185: "empty tbl layout",
186: "invalid character in tbl layout",
187: "unmatched parenthesis in tbl layout",
188: "tbl without any data cells",
189: "ignoring data in spanned tbl cell",
190: "ignoring extra tbl data cells",
191: "data block open at end of tbl",
192:
193: /* related to document structure and macros */
194: "duplicate prologue macro",
195: "skipping late title macro",
196: "input stack limit exceeded, infinite loop?",
197: "skipping bad character",
198: "skipping unknown macro",
199: "ignoring request outside macro",
200: "skipping insecure request",
201: "skipping item outside list",
202: "skipping column outside column list",
203: "skipping end of block that is not open",
204: "fewer RS blocks open, skipping",
205: "inserting missing end of block",
206: "appending missing end of block",
207:
208: /* related to request and macro arguments */
209: "escaped character not allowed in a name",
210: "using macro argument outside macro",
211: "argument number is not numeric",
212: "NOT IMPLEMENTED: Bd -file",
213: "skipping display without arguments",
214: "missing list type, using -item",
215: "argument is not numeric, using 1",
216: "argument is not a character",
217: "missing manual name, using \"\"",
218: "uname(3) system call failed, using UNKNOWN",
219: "unknown standard specifier",
220: "skipping request without numeric argument",
221: "excessive shift",
222: "NOT IMPLEMENTED: .so with absolute path or \"..\"",
223: ".so request failed",
224: "skipping all arguments",
225: "skipping excess arguments",
226: "divide by zero",
227:
228: "unsupported feature",
229: "input too large",
230: "unsupported control character",
1.3 schwarze 231: "unsupported escape sequence",
1.1 schwarze 232: "unsupported roff request",
233: "nested .while loops",
234: "end of scope with open .while loop",
235: "end of .while loop in inner scope",
236: "cannot continue this .while loop",
237: "eqn delim option in tbl",
238: "unsupported tbl layout modifier",
239: "ignoring macro in table",
1.5 schwarze 240:
241: /* bad command line arguments */
242: NULL,
243: "bad command line argument",
244: "duplicate command line argument",
245: "option has a superfluous value",
246: "missing option value",
247: "bad option value",
248: "duplicate option value",
249: "no such tag",
250:
251: /* system errors */
252: NULL,
253: "dup",
254: "exec",
255: "fdopen",
256: "fflush",
257: "fork",
258: "fstat",
259: "getline",
260: "glob",
261: "gzclose",
262: "gzdopen",
263: "mkstemp",
264: "open",
265: "pledge",
266: "read",
267: "wait",
268: "write",
1.1 schwarze 269: };
270:
1.4 schwarze 271: static FILE *fileptr = NULL;
1.1 schwarze 272: static const char *filename = NULL;
1.5 schwarze 273: static enum mandocerr min_type = MANDOCERR_BADARG;
1.1 schwarze 274: static enum mandoclevel rc = MANDOCLEVEL_OK;
275:
276:
277: void
278: mandoc_msg_setoutfile(FILE *fp)
279: {
280: fileptr = fp;
281: }
282:
283: const char *
284: mandoc_msg_getinfilename(void)
285: {
286: return filename;
287: }
288:
289: void
290: mandoc_msg_setinfilename(const char *fn)
291: {
292: filename = fn;
293: }
294:
295: enum mandocerr
296: mandoc_msg_getmin(void)
297: {
298: return min_type;
299: }
300:
301: void
302: mandoc_msg_setmin(enum mandocerr t)
303: {
304: min_type = t;
305: }
306:
307: enum mandoclevel
308: mandoc_msg_getrc(void)
309: {
310: return rc;
311: }
312:
313: void
314: mandoc_msg_setrc(enum mandoclevel level)
315: {
316: if (rc < level)
317: rc = level;
318: }
319:
320: void
1.2 schwarze 321: mandoc_msg(enum mandocerr t, int line, int col, const char *fmt, ...)
1.1 schwarze 322: {
323: va_list ap;
324: enum mandoclevel level;
325:
1.5 schwarze 326: if (t < min_type)
1.1 schwarze 327: return;
328:
1.5 schwarze 329: level = MANDOCLEVEL_SYSERR;
1.1 schwarze 330: while (t < lowest_type[level])
331: level--;
332: mandoc_msg_setrc(level);
333:
334: if (fileptr == NULL)
335: return;
336:
337: fprintf(fileptr, "%s:", getprogname());
338: if (filename != NULL)
339: fprintf(fileptr, " %s:", filename);
340:
341: if (line > 0)
342: fprintf(fileptr, "%d:%d:", line, col + 1);
343:
344: fprintf(fileptr, " %s", level_name[level]);
345: if (type_message[t] != NULL)
346: fprintf(fileptr, ": %s", type_message[t]);
347:
348: if (fmt != NULL) {
349: fprintf(fileptr, ": ");
350: va_start(ap, fmt);
351: vfprintf(fileptr, fmt, ap);
352: va_end(ap);
353: }
354: fputc('\n', fileptr);
1.6 schwarze 355: }
356:
357: void
358: mandoc_msg_summary(void)
359: {
360: if (fileptr != NULL && rc != MANDOCLEVEL_OK)
361: fprintf(fileptr,
362: "%s: see above the output for %s messages\n",
363: getprogname(), level_name[rc]);
1.1 schwarze 364: }