GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mandoc/mandoc_xr.c Lines: 47 50 94.0 %
Date: 2017-11-07 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
25102
	unsigned int		 slot;
41
42
12551
	if (xr_hash == NULL)
43
		return;
44
42136
	for (xr = ohash_first(xr_hash, &slot); xr != NULL;
45
8517
	     xr = ohash_next(xr_hash, &slot))
46
8517
		free(xr);
47
12551
	ohash_delete(xr_hash);
48
25102
}
49
50
void
51
mandoc_xr_reset(void)
52
{
53
25102
	if (xr_hash == NULL)
54
12551
		xr_hash = mandoc_malloc(sizeof(*xr_hash));
55
	else
56
		mandoc_xr_clear();
57
12551
	mandoc_ohash_init(xr_hash, 5,
58
	    offsetof(struct mandoc_xr, hashkey));
59
12551
	xr_first = xr_last = NULL;
60
12551
}
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
204758
	const char		 *pend;
67
	size_t			  ssz, nsz, tsz;
68
	unsigned int		  slot;
69
	int			  ret;
70
	uint32_t		  hv;
71
72
102379
	if (xr_hash == NULL)
73
93678
		return 0;
74
75
8701
	ssz = strlen(sec) + 1;
76
8701
	nsz = strlen(name) + 1;
77
8701
	tsz = ssz + nsz;
78
8701
	xr = mandoc_malloc(sizeof(*xr) + tsz);
79
8701
	xr->next = NULL;
80
8701
	xr->sec = xr->hashkey;
81
8701
	xr->name = xr->hashkey + ssz;
82
8701
	xr->line = line;
83
8701
	xr->pos = pos;
84
8701
	xr->count = 1;
85
8701
	memcpy(xr->sec, sec, ssz);
86
8701
	memcpy(xr->name, name, nsz);
87
88
8701
	pend = xr->hashkey + tsz;
89
8701
	hv = ohash_interval(xr->hashkey, &pend);
90
8701
	slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
91
8701
	if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
92
8517
		ohash_insert(xr_hash, slot, xr);
93
17034
		if (xr_first == NULL)
94
			xr_first = xr;
95
		else
96
8517
			xr_last->next = xr;
97
8517
		xr_last = xr;
98
8517
		return 0;
99
	}
100
101
184
	oxr->count++;
102
184
	ret = (oxr->line == -1) ^ (xr->line == -1);
103
184
	if (xr->line == -1)
104
		oxr->line = -1;
105
184
	free(xr);
106
184
	return ret;
107
102379
}
108
109
struct mandoc_xr *
110
mandoc_xr_get(void)
111
{
112
4122
	return xr_first;
113
}
114
115
void
116
mandoc_xr_free(void)
117
{
118
25102
	mandoc_xr_clear();
119
12551
	free(xr_hash);
120
12551
	xr_hash = NULL;
121
12551
}