GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mandoc/mandoc_xr.c Lines: 47 50 94.0 %
Date: 2017-11-13 Branches: 9 12 75.0 %

Line Branch Exec Source
1
/*	$OpenBSD: mandoc_xr.c,v 1.3 2017/07/02 21:17:12 schwarze Exp $ */
2
/*
3
 * Copyright (c) 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
#include <stdint.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "mandoc_aux.h"
26
#include "mandoc_ohash.h"
27
#include "mandoc_xr.h"
28
29
static struct ohash	 *xr_hash = NULL;
30
static struct mandoc_xr	 *xr_first = NULL;
31
static struct mandoc_xr	 *xr_last = NULL;
32
33
static void		  mandoc_xr_clear(void);
34
35
36
static void
37
mandoc_xr_clear(void)
38
{
39
	struct mandoc_xr	*xr;
40
8392
	unsigned int		 slot;
41
42
4196
	if (xr_hash == NULL)
43
		return;
44
13968
	for (xr = ohash_first(xr_hash, &slot); xr != NULL;
45
2788
	     xr = ohash_next(xr_hash, &slot))
46
2788
		free(xr);
47
4196
	ohash_delete(xr_hash);
48
8392
}
49
50
void
51
mandoc_xr_reset(void)
52
{
53
8392
	if (xr_hash == NULL)
54
4196
		xr_hash = mandoc_malloc(sizeof(*xr_hash));
55
	else
56
		mandoc_xr_clear();
57
4196
	mandoc_ohash_init(xr_hash, 5,
58
	    offsetof(struct mandoc_xr, hashkey));
59
4196
	xr_first = xr_last = NULL;
60
4196
}
61
62
int
63
mandoc_xr_add(const char *sec, const char *name, int line, int pos)
64
{
65
	struct mandoc_xr	 *xr, *oxr;
66
68286
	const char		 *pend;
67
	size_t			  ssz, nsz, tsz;
68
	unsigned int		  slot;
69
	int			  ret;
70
	uint32_t		  hv;
71
72
34143
	if (xr_hash == NULL)
73
31301
		return 0;
74
75
2842
	ssz = strlen(sec) + 1;
76
2842
	nsz = strlen(name) + 1;
77
2842
	tsz = ssz + nsz;
78
2842
	xr = mandoc_malloc(sizeof(*xr) + tsz);
79
2842
	xr->next = NULL;
80
2842
	xr->sec = xr->hashkey;
81
2842
	xr->name = xr->hashkey + ssz;
82
2842
	xr->line = line;
83
2842
	xr->pos = pos;
84
2842
	xr->count = 1;
85
2842
	memcpy(xr->sec, sec, ssz);
86
2842
	memcpy(xr->name, name, nsz);
87
88
2842
	pend = xr->hashkey + tsz;
89
2842
	hv = ohash_interval(xr->hashkey, &pend);
90
2842
	slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
91
2842
	if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
92
2788
		ohash_insert(xr_hash, slot, xr);
93
5576
		if (xr_first == NULL)
94
			xr_first = xr;
95
		else
96
2788
			xr_last->next = xr;
97
2788
		xr_last = xr;
98
2788
		return 0;
99
	}
100
101
54
	oxr->count++;
102
54
	ret = (oxr->line == -1) ^ (xr->line == -1);
103
54
	if (xr->line == -1)
104
		oxr->line = -1;
105
54
	free(xr);
106
54
	return ret;
107
34143
}
108
109
struct mandoc_xr *
110
mandoc_xr_get(void)
111
{
112
1374
	return xr_first;
113
}
114
115
void
116
mandoc_xr_free(void)
117
{
118
8392
	mandoc_xr_clear();
119
4196
	free(xr_hash);
120
4196
	xr_hash = NULL;
121
4196
}