1*6d38604fSBaptiste Daroussin /* $Id: mandoc_xr.c,v 1.4 2020/06/22 19:20:40 schwarze Exp $ */
261d06d6bSBaptiste Daroussin /*
361d06d6bSBaptiste Daroussin * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
461d06d6bSBaptiste Daroussin *
561d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any
661d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above
761d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies.
861d06d6bSBaptiste Daroussin *
961d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1061d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1161d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1261d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1361d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1461d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1561d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1661d06d6bSBaptiste Daroussin */
17*6d38604fSBaptiste Daroussin #include "config.h"
18*6d38604fSBaptiste Daroussin
1961d06d6bSBaptiste Daroussin #include <sys/types.h>
2061d06d6bSBaptiste Daroussin
2161d06d6bSBaptiste Daroussin #include <assert.h>
2261d06d6bSBaptiste Daroussin #include <stddef.h>
2361d06d6bSBaptiste Daroussin #include <stdint.h>
2461d06d6bSBaptiste Daroussin #include <stdlib.h>
2561d06d6bSBaptiste Daroussin #include <string.h>
2661d06d6bSBaptiste Daroussin
2761d06d6bSBaptiste Daroussin #include "mandoc_aux.h"
2861d06d6bSBaptiste Daroussin #include "mandoc_ohash.h"
2961d06d6bSBaptiste Daroussin #include "mandoc_xr.h"
3061d06d6bSBaptiste Daroussin
3161d06d6bSBaptiste Daroussin static struct ohash *xr_hash = NULL;
3261d06d6bSBaptiste Daroussin static struct mandoc_xr *xr_first = NULL;
3361d06d6bSBaptiste Daroussin static struct mandoc_xr *xr_last = NULL;
3461d06d6bSBaptiste Daroussin
3561d06d6bSBaptiste Daroussin static void mandoc_xr_clear(void);
3661d06d6bSBaptiste Daroussin
3761d06d6bSBaptiste Daroussin
3861d06d6bSBaptiste Daroussin static void
mandoc_xr_clear(void)3961d06d6bSBaptiste Daroussin mandoc_xr_clear(void)
4061d06d6bSBaptiste Daroussin {
4161d06d6bSBaptiste Daroussin struct mandoc_xr *xr;
4261d06d6bSBaptiste Daroussin unsigned int slot;
4361d06d6bSBaptiste Daroussin
4461d06d6bSBaptiste Daroussin if (xr_hash == NULL)
4561d06d6bSBaptiste Daroussin return;
4661d06d6bSBaptiste Daroussin for (xr = ohash_first(xr_hash, &slot); xr != NULL;
4761d06d6bSBaptiste Daroussin xr = ohash_next(xr_hash, &slot))
4861d06d6bSBaptiste Daroussin free(xr);
4961d06d6bSBaptiste Daroussin ohash_delete(xr_hash);
5061d06d6bSBaptiste Daroussin }
5161d06d6bSBaptiste Daroussin
5261d06d6bSBaptiste Daroussin void
mandoc_xr_reset(void)5361d06d6bSBaptiste Daroussin mandoc_xr_reset(void)
5461d06d6bSBaptiste Daroussin {
5561d06d6bSBaptiste Daroussin if (xr_hash == NULL)
5661d06d6bSBaptiste Daroussin xr_hash = mandoc_malloc(sizeof(*xr_hash));
5761d06d6bSBaptiste Daroussin else
5861d06d6bSBaptiste Daroussin mandoc_xr_clear();
5961d06d6bSBaptiste Daroussin mandoc_ohash_init(xr_hash, 5,
6061d06d6bSBaptiste Daroussin offsetof(struct mandoc_xr, hashkey));
6161d06d6bSBaptiste Daroussin xr_first = xr_last = NULL;
6261d06d6bSBaptiste Daroussin }
6361d06d6bSBaptiste Daroussin
6461d06d6bSBaptiste Daroussin int
mandoc_xr_add(const char * sec,const char * name,int line,int pos)6561d06d6bSBaptiste Daroussin mandoc_xr_add(const char *sec, const char *name, int line, int pos)
6661d06d6bSBaptiste Daroussin {
6761d06d6bSBaptiste Daroussin struct mandoc_xr *xr, *oxr;
6861d06d6bSBaptiste Daroussin const char *pend;
6961d06d6bSBaptiste Daroussin size_t ssz, nsz, tsz;
7061d06d6bSBaptiste Daroussin unsigned int slot;
7161d06d6bSBaptiste Daroussin int ret;
7261d06d6bSBaptiste Daroussin uint32_t hv;
7361d06d6bSBaptiste Daroussin
7461d06d6bSBaptiste Daroussin if (xr_hash == NULL)
7561d06d6bSBaptiste Daroussin return 0;
7661d06d6bSBaptiste Daroussin
7761d06d6bSBaptiste Daroussin ssz = strlen(sec) + 1;
7861d06d6bSBaptiste Daroussin nsz = strlen(name) + 1;
7961d06d6bSBaptiste Daroussin tsz = ssz + nsz;
8061d06d6bSBaptiste Daroussin xr = mandoc_malloc(sizeof(*xr) + tsz);
8161d06d6bSBaptiste Daroussin xr->next = NULL;
8261d06d6bSBaptiste Daroussin xr->sec = xr->hashkey;
8361d06d6bSBaptiste Daroussin xr->name = xr->hashkey + ssz;
8461d06d6bSBaptiste Daroussin xr->line = line;
8561d06d6bSBaptiste Daroussin xr->pos = pos;
8661d06d6bSBaptiste Daroussin xr->count = 1;
8761d06d6bSBaptiste Daroussin memcpy(xr->sec, sec, ssz);
8861d06d6bSBaptiste Daroussin memcpy(xr->name, name, nsz);
8961d06d6bSBaptiste Daroussin
9061d06d6bSBaptiste Daroussin pend = xr->hashkey + tsz;
9161d06d6bSBaptiste Daroussin hv = ohash_interval(xr->hashkey, &pend);
9261d06d6bSBaptiste Daroussin slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
9361d06d6bSBaptiste Daroussin if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
9461d06d6bSBaptiste Daroussin ohash_insert(xr_hash, slot, xr);
9561d06d6bSBaptiste Daroussin if (xr_first == NULL)
9661d06d6bSBaptiste Daroussin xr_first = xr;
9761d06d6bSBaptiste Daroussin else
9861d06d6bSBaptiste Daroussin xr_last->next = xr;
9961d06d6bSBaptiste Daroussin xr_last = xr;
10061d06d6bSBaptiste Daroussin return 0;
10161d06d6bSBaptiste Daroussin }
10261d06d6bSBaptiste Daroussin
10361d06d6bSBaptiste Daroussin oxr->count++;
10461d06d6bSBaptiste Daroussin ret = (oxr->line == -1) ^ (xr->line == -1);
10561d06d6bSBaptiste Daroussin if (xr->line == -1)
10661d06d6bSBaptiste Daroussin oxr->line = -1;
10761d06d6bSBaptiste Daroussin free(xr);
10861d06d6bSBaptiste Daroussin return ret;
10961d06d6bSBaptiste Daroussin }
11061d06d6bSBaptiste Daroussin
11161d06d6bSBaptiste Daroussin struct mandoc_xr *
mandoc_xr_get(void)11261d06d6bSBaptiste Daroussin mandoc_xr_get(void)
11361d06d6bSBaptiste Daroussin {
11461d06d6bSBaptiste Daroussin return xr_first;
11561d06d6bSBaptiste Daroussin }
11661d06d6bSBaptiste Daroussin
11761d06d6bSBaptiste Daroussin void
mandoc_xr_free(void)11861d06d6bSBaptiste Daroussin mandoc_xr_free(void)
11961d06d6bSBaptiste Daroussin {
12061d06d6bSBaptiste Daroussin mandoc_xr_clear();
12161d06d6bSBaptiste Daroussin free(xr_hash);
12261d06d6bSBaptiste Daroussin xr_hash = NULL;
12361d06d6bSBaptiste Daroussin }
124