GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mandoc/roff_validate.c Lines: 22 22 100.0 %
Date: 2017-11-13 Branches: 13 28 46.4 %

Line Branch Exec Source
1
/*	$OpenBSD: roff_validate.c,v 1.9 2017/06/14 22:50:37 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
43886
	n = man->last;
53
21943
	assert(n->tok < ROFF_MAX);
54
21943
	if (roff_valids[n->tok] != NULL)
55
21833
		(*roff_valids[n->tok])(man, n);
56
21943
}
57
58
static void
59
roff_valid_ft(ROFF_VALID_ARGS)
60
{
61
	char	*cp;
62
63
43666
	if (n->child == NULL) {
64
16
		man->next = ROFF_NEXT_CHILD;
65
16
		roff_word_alloc(man, n->line, n->pos, "P");
66
16
		man->last = n;
67
16
		return;
68
	}
69
70
21817
	cp = n->child->string;
71


21817
	switch (*cp) {
72
	case '1':
73
	case '2':
74
	case '3':
75
	case '4':
76
	case 'I':
77
	case 'P':
78
	case 'R':
79
10911
		if (cp[1] == '\0')
80
10911
			return;
81
		break;
82
	case 'B':
83

29
		if (cp[1] == '\0' || (cp[1] == 'I' && cp[2] == '\0'))
84
29
			return;
85
		break;
86
	case 'C':
87

21724
		if (cp[1] == 'W' && cp[2] == '\0')
88
10862
			return;
89
		break;
90
	default:
91
		break;
92
	}
93
94
30
	mandoc_vmsg(MANDOCERR_FT_BAD, man->parse,
95
15
	    n->line, n->pos, "ft %s", cp);
96
15
	roff_node_delete(man, n);
97
21848
}