GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mandoc/tree.c Lines: 0 186 0.0 %
Date: 2017-11-13 Branches: 0 210 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: tree.c,v 1.44 2017/07/08 14:51:01 schwarze Exp $ */
2
/*
3
 * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4
 * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
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 <sys/types.h>
19
20
#include <assert.h>
21
#include <limits.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <time.h>
25
26
#include "mandoc.h"
27
#include "roff.h"
28
#include "mdoc.h"
29
#include "man.h"
30
#include "main.h"
31
32
static	void	print_box(const struct eqn_box *, int);
33
static	void	print_man(const struct roff_node *, int);
34
static	void	print_meta(const struct roff_meta *);
35
static	void	print_mdoc(const struct roff_node *, int);
36
static	void	print_span(const struct tbl_span *, int);
37
38
39
void
40
tree_mdoc(void *arg, const struct roff_man *mdoc)
41
{
42
	print_meta(&mdoc->meta);
43
	putchar('\n');
44
	print_mdoc(mdoc->first->child, 0);
45
}
46
47
void
48
tree_man(void *arg, const struct roff_man *man)
49
{
50
	print_meta(&man->meta);
51
	if (man->meta.hasbody == 0)
52
		puts("body  = empty");
53
	putchar('\n');
54
	print_man(man->first->child, 0);
55
}
56
57
static void
58
print_meta(const struct roff_meta *meta)
59
{
60
	if (meta->title != NULL)
61
		printf("title = \"%s\"\n", meta->title);
62
	if (meta->name != NULL)
63
		printf("name  = \"%s\"\n", meta->name);
64
	if (meta->msec != NULL)
65
		printf("sec   = \"%s\"\n", meta->msec);
66
	if (meta->vol != NULL)
67
		printf("vol   = \"%s\"\n", meta->vol);
68
	if (meta->arch != NULL)
69
		printf("arch  = \"%s\"\n", meta->arch);
70
	if (meta->os != NULL)
71
		printf("os    = \"%s\"\n", meta->os);
72
	if (meta->date != NULL)
73
		printf("date  = \"%s\"\n", meta->date);
74
}
75
76
static void
77
print_mdoc(const struct roff_node *n, int indent)
78
{
79
	const char	 *p, *t;
80
	int		  i, j;
81
	size_t		  argc;
82
	struct mdoc_argv *argv;
83
84
	if (n == NULL)
85
		return;
86
87
	argv = NULL;
88
	argc = 0;
89
	t = p = NULL;
90
91
	switch (n->type) {
92
	case ROFFT_ROOT:
93
		t = "root";
94
		break;
95
	case ROFFT_BLOCK:
96
		t = "block";
97
		break;
98
	case ROFFT_HEAD:
99
		t = "head";
100
		break;
101
	case ROFFT_BODY:
102
		if (n->end)
103
			t = "body-end";
104
		else
105
			t = "body";
106
		break;
107
	case ROFFT_TAIL:
108
		t = "tail";
109
		break;
110
	case ROFFT_ELEM:
111
		t = "elem";
112
		break;
113
	case ROFFT_TEXT:
114
		t = "text";
115
		break;
116
	case ROFFT_TBL:
117
		break;
118
	case ROFFT_EQN:
119
		t = "eqn";
120
		break;
121
	default:
122
		abort();
123
	}
124
125
	switch (n->type) {
126
	case ROFFT_TEXT:
127
		p = n->string;
128
		break;
129
	case ROFFT_BODY:
130
		p = roff_name[n->tok];
131
		break;
132
	case ROFFT_HEAD:
133
		p = roff_name[n->tok];
134
		break;
135
	case ROFFT_TAIL:
136
		p = roff_name[n->tok];
137
		break;
138
	case ROFFT_ELEM:
139
		p = roff_name[n->tok];
140
		if (n->args) {
141
			argv = n->args->argv;
142
			argc = n->args->argc;
143
		}
144
		break;
145
	case ROFFT_BLOCK:
146
		p = roff_name[n->tok];
147
		if (n->args) {
148
			argv = n->args->argv;
149
			argc = n->args->argc;
150
		}
151
		break;
152
	case ROFFT_TBL:
153
		break;
154
	case ROFFT_EQN:
155
		p = "EQ";
156
		break;
157
	case ROFFT_ROOT:
158
		p = "root";
159
		break;
160
	default:
161
		abort();
162
	}
163
164
	if (n->span) {
165
		assert(NULL == p && NULL == t);
166
		print_span(n->span, indent);
167
	} else {
168
		for (i = 0; i < indent; i++)
169
			putchar(' ');
170
171
		printf("%s (%s)", p, t);
172
173
		for (i = 0; i < (int)argc; i++) {
174
			printf(" -%s", mdoc_argnames[argv[i].arg]);
175
			if (argv[i].sz > 0)
176
				printf(" [");
177
			for (j = 0; j < (int)argv[i].sz; j++)
178
				printf(" [%s]", argv[i].value[j]);
179
			if (argv[i].sz > 0)
180
				printf(" ]");
181
		}
182
183
		putchar(' ');
184
		if (NODE_DELIMO & n->flags)
185
			putchar('(');
186
		if (NODE_LINE & n->flags)
187
			putchar('*');
188
		printf("%d:%d", n->line, n->pos + 1);
189
		if (NODE_DELIMC & n->flags)
190
			putchar(')');
191
		if (NODE_EOS & n->flags)
192
			putchar('.');
193
		if (NODE_BROKEN & n->flags)
194
			printf(" BROKEN");
195
		if (NODE_NOSRC & n->flags)
196
			printf(" NOSRC");
197
		if (NODE_NOPRT & n->flags)
198
			printf(" NOPRT");
199
		putchar('\n');
200
	}
201
202
	if (n->eqn)
203
		print_box(n->eqn->first, indent + 4);
204
	if (n->child)
205
		print_mdoc(n->child, indent +
206
		    (n->type == ROFFT_BLOCK ? 2 : 4));
207
	if (n->next)
208
		print_mdoc(n->next, indent);
209
}
210
211
static void
212
print_man(const struct roff_node *n, int indent)
213
{
214
	const char	 *p, *t;
215
	int		  i;
216
217
	if (n == NULL)
218
		return;
219
220
	t = p = NULL;
221
222
	switch (n->type) {
223
	case ROFFT_ROOT:
224
		t = "root";
225
		break;
226
	case ROFFT_ELEM:
227
		t = "elem";
228
		break;
229
	case ROFFT_TEXT:
230
		t = "text";
231
		break;
232
	case ROFFT_BLOCK:
233
		t = "block";
234
		break;
235
	case ROFFT_HEAD:
236
		t = "head";
237
		break;
238
	case ROFFT_BODY:
239
		t = "body";
240
		break;
241
	case ROFFT_TBL:
242
		break;
243
	case ROFFT_EQN:
244
		t = "eqn";
245
		break;
246
	default:
247
		abort();
248
	}
249
250
	switch (n->type) {
251
	case ROFFT_TEXT:
252
		p = n->string;
253
		break;
254
	case ROFFT_ELEM:
255
	case ROFFT_BLOCK:
256
	case ROFFT_HEAD:
257
	case ROFFT_BODY:
258
		p = roff_name[n->tok];
259
		break;
260
	case ROFFT_ROOT:
261
		p = "root";
262
		break;
263
	case ROFFT_TBL:
264
		break;
265
	case ROFFT_EQN:
266
		p = "EQ";
267
		break;
268
	default:
269
		abort();
270
	}
271
272
	if (n->span) {
273
		assert(NULL == p && NULL == t);
274
		print_span(n->span, indent);
275
	} else {
276
		for (i = 0; i < indent; i++)
277
			putchar(' ');
278
		printf("%s (%s) ", p, t);
279
		if (NODE_LINE & n->flags)
280
			putchar('*');
281
		printf("%d:%d", n->line, n->pos + 1);
282
		if (NODE_EOS & n->flags)
283
			putchar('.');
284
		putchar('\n');
285
	}
286
287
	if (n->eqn)
288
		print_box(n->eqn->first, indent + 4);
289
	if (n->child)
290
		print_man(n->child, indent +
291
		    (n->type == ROFFT_BLOCK ? 2 : 4));
292
	if (n->next)
293
		print_man(n->next, indent);
294
}
295
296
static void
297
print_box(const struct eqn_box *ep, int indent)
298
{
299
	int		 i;
300
	const char	*t;
301
302
	static const char *posnames[] = {
303
	    NULL, "sup", "subsup", "sub",
304
	    "to", "from", "fromto",
305
	    "over", "sqrt", NULL };
306
307
	if (NULL == ep)
308
		return;
309
	for (i = 0; i < indent; i++)
310
		putchar(' ');
311
312
	t = NULL;
313
	switch (ep->type) {
314
	case EQN_LIST:
315
		t = "eqn-list";
316
		break;
317
	case EQN_SUBEXPR:
318
		t = "eqn-expr";
319
		break;
320
	case EQN_TEXT:
321
		t = "eqn-text";
322
		break;
323
	case EQN_PILE:
324
		t = "eqn-pile";
325
		break;
326
	case EQN_MATRIX:
327
		t = "eqn-matrix";
328
		break;
329
	}
330
331
	fputs(t, stdout);
332
	if (ep->pos)
333
		printf(" pos=%s", posnames[ep->pos]);
334
	if (ep->left)
335
		printf(" left=\"%s\"", ep->left);
336
	if (ep->right)
337
		printf(" right=\"%s\"", ep->right);
338
	if (ep->top)
339
		printf(" top=\"%s\"", ep->top);
340
	if (ep->bottom)
341
		printf(" bottom=\"%s\"", ep->bottom);
342
	if (ep->text)
343
		printf(" text=\"%s\"", ep->text);
344
	if (ep->font)
345
		printf(" font=%d", ep->font);
346
	if (ep->size != EQN_DEFSIZE)
347
		printf(" size=%d", ep->size);
348
	if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
349
		printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
350
	else if (ep->args)
351
		printf(" args=%zu", ep->args);
352
	putchar('\n');
353
354
	print_box(ep->first, indent + 4);
355
	print_box(ep->next, indent);
356
}
357
358
static void
359
print_span(const struct tbl_span *sp, int indent)
360
{
361
	const struct tbl_dat *dp;
362
	int		 i;
363
364
	for (i = 0; i < indent; i++)
365
		putchar(' ');
366
367
	switch (sp->pos) {
368
	case TBL_SPAN_HORIZ:
369
		putchar('-');
370
		return;
371
	case TBL_SPAN_DHORIZ:
372
		putchar('=');
373
		return;
374
	default:
375
		break;
376
	}
377
378
	for (dp = sp->first; dp; dp = dp->next) {
379
		switch (dp->pos) {
380
		case TBL_DATA_HORIZ:
381
		case TBL_DATA_NHORIZ:
382
			putchar('-');
383
			continue;
384
		case TBL_DATA_DHORIZ:
385
		case TBL_DATA_NDHORIZ:
386
			putchar('=');
387
			continue;
388
		default:
389
			break;
390
		}
391
		printf("[\"%s\"", dp->string ? dp->string : "");
392
		if (dp->spans)
393
			printf("(%d)", dp->spans);
394
		if (NULL == dp->layout)
395
			putchar('*');
396
		putchar(']');
397
		putchar(' ');
398
	}
399
400
	printf("(tbl) %d:1\n", sp->line);
401
}