]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/mandoc/roff_validate.c
Merge llvm, clang, compiler-rt, libc++, lld, and lldb release_80 branch
[FreeBSD/FreeBSD.git] / contrib / mandoc / roff_validate.c
1 /*      $Id: roff_validate.c,v 1.9 2017/06/14 22:51:25 schwarze Exp $ */
2 /*
3  * Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <sys/types.h>
18
19 #include <assert.h>
20 #include <stddef.h>
21
22 #include "mandoc.h"
23 #include "roff.h"
24 #include "libmandoc.h"
25 #include "roff_int.h"
26
27 #define ROFF_VALID_ARGS struct roff_man *man, struct roff_node *n
28
29 typedef void    (*roff_valid_fp)(ROFF_VALID_ARGS);
30
31 static  void      roff_valid_ft(ROFF_VALID_ARGS);
32
33 static  const roff_valid_fp roff_valids[ROFF_MAX] = {
34         NULL,  /* br */
35         NULL,  /* ce */
36         roff_valid_ft,  /* ft */
37         NULL,  /* ll */
38         NULL,  /* mc */
39         NULL,  /* po */
40         NULL,  /* rj */
41         NULL,  /* sp */
42         NULL,  /* ta */
43         NULL,  /* ti */
44 };
45
46
47 void
48 roff_validate(struct roff_man *man)
49 {
50         struct roff_node        *n;
51
52         n = man->last;
53         assert(n->tok < ROFF_MAX);
54         if (roff_valids[n->tok] != NULL)
55                 (*roff_valids[n->tok])(man, n);
56 }
57
58 static void
59 roff_valid_ft(ROFF_VALID_ARGS)
60 {
61         char    *cp;
62
63         if (n->child == NULL) {
64                 man->next = ROFF_NEXT_CHILD;
65                 roff_word_alloc(man, n->line, n->pos, "P");
66                 man->last = n;
67                 return;
68         }
69
70         cp = n->child->string;
71         switch (*cp) {
72         case '1':
73         case '2':
74         case '3':
75         case '4':
76         case 'I':
77         case 'P':
78         case 'R':
79                 if (cp[1] == '\0')
80                         return;
81                 break;
82         case 'B':
83                 if (cp[1] == '\0' || (cp[1] == 'I' && cp[2] == '\0'))
84                         return;
85                 break;
86         case 'C':
87                 if (cp[1] == 'W' && cp[2] == '\0')
88                         return;
89                 break;
90         default:
91                 break;
92         }
93
94         mandoc_vmsg(MANDOCERR_FT_BAD, man->parse,
95             n->line, n->pos, "ft %s", cp);
96         roff_node_delete(man, n);
97 }