xref: /illumos-gate/usr/src/cmd/mandoc/mandoc_xr.c (revision 4d131170)
1*4d131170SRobert Mustacchi /* $Id: mandoc_xr.c,v 1.4 2020/06/22 19:20:40 schwarze Exp $ */
2c66b8046SYuri Pankov /*
3c66b8046SYuri Pankov  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
4c66b8046SYuri Pankov  *
5c66b8046SYuri Pankov  * Permission to use, copy, modify, and distribute this software for any
6c66b8046SYuri Pankov  * purpose with or without fee is hereby granted, provided that the above
7c66b8046SYuri Pankov  * copyright notice and this permission notice appear in all copies.
8c66b8046SYuri Pankov  *
9c66b8046SYuri Pankov  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10c66b8046SYuri Pankov  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11c66b8046SYuri Pankov  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12c66b8046SYuri Pankov  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13c66b8046SYuri Pankov  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14c66b8046SYuri Pankov  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15c66b8046SYuri Pankov  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16c66b8046SYuri Pankov  */
17*4d131170SRobert Mustacchi #include "config.h"
18*4d131170SRobert Mustacchi 
19c66b8046SYuri Pankov #include <sys/types.h>
20c66b8046SYuri Pankov 
21c66b8046SYuri Pankov #include <assert.h>
22c66b8046SYuri Pankov #include <stddef.h>
23c66b8046SYuri Pankov #include <stdint.h>
24c66b8046SYuri Pankov #include <stdlib.h>
25c66b8046SYuri Pankov #include <string.h>
26c66b8046SYuri Pankov 
27c66b8046SYuri Pankov #include "mandoc_aux.h"
28c66b8046SYuri Pankov #include "mandoc_ohash.h"
29c66b8046SYuri Pankov #include "mandoc_xr.h"
30c66b8046SYuri Pankov 
31c66b8046SYuri Pankov static struct ohash	 *xr_hash = NULL;
32c66b8046SYuri Pankov static struct mandoc_xr	 *xr_first = NULL;
33c66b8046SYuri Pankov static struct mandoc_xr	 *xr_last = NULL;
34c66b8046SYuri Pankov 
35c66b8046SYuri Pankov static void		  mandoc_xr_clear(void);
36c66b8046SYuri Pankov 
37c66b8046SYuri Pankov 
38c66b8046SYuri Pankov static void
mandoc_xr_clear(void)39c66b8046SYuri Pankov mandoc_xr_clear(void)
40c66b8046SYuri Pankov {
41c66b8046SYuri Pankov 	struct mandoc_xr	*xr;
42c66b8046SYuri Pankov 	unsigned int		 slot;
43c66b8046SYuri Pankov 
44c66b8046SYuri Pankov 	if (xr_hash == NULL)
45c66b8046SYuri Pankov 		return;
46c66b8046SYuri Pankov 	for (xr = ohash_first(xr_hash, &slot); xr != NULL;
47c66b8046SYuri Pankov 	     xr = ohash_next(xr_hash, &slot))
48c66b8046SYuri Pankov 		free(xr);
49c66b8046SYuri Pankov 	ohash_delete(xr_hash);
50c66b8046SYuri Pankov }
51c66b8046SYuri Pankov 
52c66b8046SYuri Pankov void
mandoc_xr_reset(void)53c66b8046SYuri Pankov mandoc_xr_reset(void)
54c66b8046SYuri Pankov {
55c66b8046SYuri Pankov 	if (xr_hash == NULL)
56c66b8046SYuri Pankov 		xr_hash = mandoc_malloc(sizeof(*xr_hash));
57c66b8046SYuri Pankov 	else
58c66b8046SYuri Pankov 		mandoc_xr_clear();
59c66b8046SYuri Pankov 	mandoc_ohash_init(xr_hash, 5,
60c66b8046SYuri Pankov 	    offsetof(struct mandoc_xr, hashkey));
61c66b8046SYuri Pankov 	xr_first = xr_last = NULL;
62c66b8046SYuri Pankov }
63c66b8046SYuri Pankov 
64c66b8046SYuri Pankov int
mandoc_xr_add(const char * sec,const char * name,int line,int pos)65c66b8046SYuri Pankov mandoc_xr_add(const char *sec, const char *name, int line, int pos)
66c66b8046SYuri Pankov {
67c66b8046SYuri Pankov 	struct mandoc_xr	 *xr, *oxr;
68c66b8046SYuri Pankov 	const char		 *pend;
69c66b8046SYuri Pankov 	size_t			  ssz, nsz, tsz;
70c66b8046SYuri Pankov 	unsigned int		  slot;
71c66b8046SYuri Pankov 	int			  ret;
72c66b8046SYuri Pankov 	uint32_t		  hv;
73c66b8046SYuri Pankov 
74c66b8046SYuri Pankov 	if (xr_hash == NULL)
75c66b8046SYuri Pankov 		return 0;
76c66b8046SYuri Pankov 
77c66b8046SYuri Pankov 	ssz = strlen(sec) + 1;
78c66b8046SYuri Pankov 	nsz = strlen(name) + 1;
79c66b8046SYuri Pankov 	tsz = ssz + nsz;
80c66b8046SYuri Pankov 	xr = mandoc_malloc(sizeof(*xr) + tsz);
81c66b8046SYuri Pankov 	xr->next = NULL;
82c66b8046SYuri Pankov 	xr->sec = xr->hashkey;
83c66b8046SYuri Pankov 	xr->name = xr->hashkey + ssz;
84c66b8046SYuri Pankov 	xr->line = line;
85c66b8046SYuri Pankov 	xr->pos = pos;
86c66b8046SYuri Pankov 	xr->count = 1;
87c66b8046SYuri Pankov 	memcpy(xr->sec, sec, ssz);
88c66b8046SYuri Pankov 	memcpy(xr->name, name, nsz);
89c66b8046SYuri Pankov 
90c66b8046SYuri Pankov 	pend = xr->hashkey + tsz;
91c66b8046SYuri Pankov 	hv = ohash_interval(xr->hashkey, &pend);
92c66b8046SYuri Pankov 	slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
93c66b8046SYuri Pankov 	if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
94c66b8046SYuri Pankov 		ohash_insert(xr_hash, slot, xr);
95c66b8046SYuri Pankov 		if (xr_first == NULL)
96c66b8046SYuri Pankov 			xr_first = xr;
97c66b8046SYuri Pankov 		else
98c66b8046SYuri Pankov 			xr_last->next = xr;
99c66b8046SYuri Pankov 		xr_last = xr;
100c66b8046SYuri Pankov 		return 0;
101c66b8046SYuri Pankov 	}
102c66b8046SYuri Pankov 
103c66b8046SYuri Pankov 	oxr->count++;
104c66b8046SYuri Pankov 	ret = (oxr->line == -1) ^ (xr->line == -1);
105c66b8046SYuri Pankov 	if (xr->line == -1)
106c66b8046SYuri Pankov 		oxr->line = -1;
107c66b8046SYuri Pankov 	free(xr);
108c66b8046SYuri Pankov 	return ret;
109c66b8046SYuri Pankov }
110c66b8046SYuri Pankov 
111c66b8046SYuri Pankov struct mandoc_xr *
mandoc_xr_get(void)112c66b8046SYuri Pankov mandoc_xr_get(void)
113c66b8046SYuri Pankov {
114c66b8046SYuri Pankov 	return xr_first;
115c66b8046SYuri Pankov }
116c66b8046SYuri Pankov 
117c66b8046SYuri Pankov void
mandoc_xr_free(void)118c66b8046SYuri Pankov mandoc_xr_free(void)
119c66b8046SYuri Pankov {
120c66b8046SYuri Pankov 	mandoc_xr_clear();
121c66b8046SYuri Pankov 	free(xr_hash);
122c66b8046SYuri Pankov 	xr_hash = NULL;
123c66b8046SYuri Pankov }
124