1*bff2a0c3Sschwarze /* $OpenBSD: mandoc_xr.c,v 1.3 2017/07/02 21:17:12 schwarze Exp $ */
219b6bef7Sschwarze /*
319b6bef7Sschwarze * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
419b6bef7Sschwarze *
519b6bef7Sschwarze * Permission to use, copy, modify, and distribute this software for any
619b6bef7Sschwarze * purpose with or without fee is hereby granted, provided that the above
719b6bef7Sschwarze * copyright notice and this permission notice appear in all copies.
819b6bef7Sschwarze *
919b6bef7Sschwarze * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1019b6bef7Sschwarze * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1119b6bef7Sschwarze * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1219b6bef7Sschwarze * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1319b6bef7Sschwarze * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1419b6bef7Sschwarze * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1519b6bef7Sschwarze * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1619b6bef7Sschwarze */
1719b6bef7Sschwarze #include <sys/types.h>
1819b6bef7Sschwarze
1919b6bef7Sschwarze #include <assert.h>
2019b6bef7Sschwarze #include <stddef.h>
2119b6bef7Sschwarze #include <stdint.h>
2219b6bef7Sschwarze #include <stdlib.h>
2319b6bef7Sschwarze #include <string.h>
2419b6bef7Sschwarze
2519b6bef7Sschwarze #include "mandoc_aux.h"
2619b6bef7Sschwarze #include "mandoc_ohash.h"
2719b6bef7Sschwarze #include "mandoc_xr.h"
2819b6bef7Sschwarze
2919b6bef7Sschwarze static struct ohash *xr_hash = NULL;
3019b6bef7Sschwarze static struct mandoc_xr *xr_first = NULL;
3119b6bef7Sschwarze static struct mandoc_xr *xr_last = NULL;
3219b6bef7Sschwarze
3319b6bef7Sschwarze static void mandoc_xr_clear(void);
3419b6bef7Sschwarze
3519b6bef7Sschwarze
3619b6bef7Sschwarze static void
mandoc_xr_clear(void)3719b6bef7Sschwarze mandoc_xr_clear(void)
3819b6bef7Sschwarze {
3919b6bef7Sschwarze struct mandoc_xr *xr;
4019b6bef7Sschwarze unsigned int slot;
4119b6bef7Sschwarze
4219b6bef7Sschwarze if (xr_hash == NULL)
4319b6bef7Sschwarze return;
4419b6bef7Sschwarze for (xr = ohash_first(xr_hash, &slot); xr != NULL;
4519b6bef7Sschwarze xr = ohash_next(xr_hash, &slot))
4619b6bef7Sschwarze free(xr);
4719b6bef7Sschwarze ohash_delete(xr_hash);
4819b6bef7Sschwarze }
4919b6bef7Sschwarze
5019b6bef7Sschwarze void
mandoc_xr_reset(void)5119b6bef7Sschwarze mandoc_xr_reset(void)
5219b6bef7Sschwarze {
5319b6bef7Sschwarze if (xr_hash == NULL)
5419b6bef7Sschwarze xr_hash = mandoc_malloc(sizeof(*xr_hash));
5519b6bef7Sschwarze else
5619b6bef7Sschwarze mandoc_xr_clear();
5719b6bef7Sschwarze mandoc_ohash_init(xr_hash, 5,
5819b6bef7Sschwarze offsetof(struct mandoc_xr, hashkey));
5919b6bef7Sschwarze xr_first = xr_last = NULL;
6019b6bef7Sschwarze }
6119b6bef7Sschwarze
6252d11c96Sschwarze int
mandoc_xr_add(const char * sec,const char * name,int line,int pos)6319b6bef7Sschwarze mandoc_xr_add(const char *sec, const char *name, int line, int pos)
6419b6bef7Sschwarze {
6552d11c96Sschwarze struct mandoc_xr *xr, *oxr;
6619b6bef7Sschwarze const char *pend;
6719b6bef7Sschwarze size_t ssz, nsz, tsz;
6819b6bef7Sschwarze unsigned int slot;
6952d11c96Sschwarze int ret;
7019b6bef7Sschwarze uint32_t hv;
7119b6bef7Sschwarze
7219b6bef7Sschwarze if (xr_hash == NULL)
7352d11c96Sschwarze return 0;
7419b6bef7Sschwarze
7519b6bef7Sschwarze ssz = strlen(sec) + 1;
7619b6bef7Sschwarze nsz = strlen(name) + 1;
7719b6bef7Sschwarze tsz = ssz + nsz;
7819b6bef7Sschwarze xr = mandoc_malloc(sizeof(*xr) + tsz);
7919b6bef7Sschwarze xr->next = NULL;
8019b6bef7Sschwarze xr->sec = xr->hashkey;
8119b6bef7Sschwarze xr->name = xr->hashkey + ssz;
8219b6bef7Sschwarze xr->line = line;
8319b6bef7Sschwarze xr->pos = pos;
84*bff2a0c3Sschwarze xr->count = 1;
8519b6bef7Sschwarze memcpy(xr->sec, sec, ssz);
8619b6bef7Sschwarze memcpy(xr->name, name, nsz);
8719b6bef7Sschwarze
8819b6bef7Sschwarze pend = xr->hashkey + tsz;
8919b6bef7Sschwarze hv = ohash_interval(xr->hashkey, &pend);
9019b6bef7Sschwarze slot = ohash_lookup_memory(xr_hash, xr->hashkey, tsz, hv);
9152d11c96Sschwarze if ((oxr = ohash_find(xr_hash, slot)) == NULL) {
9219b6bef7Sschwarze ohash_insert(xr_hash, slot, xr);
9319b6bef7Sschwarze if (xr_first == NULL)
9419b6bef7Sschwarze xr_first = xr;
9519b6bef7Sschwarze else
9619b6bef7Sschwarze xr_last->next = xr;
9719b6bef7Sschwarze xr_last = xr;
9852d11c96Sschwarze return 0;
9952d11c96Sschwarze }
10052d11c96Sschwarze
101*bff2a0c3Sschwarze oxr->count++;
10252d11c96Sschwarze ret = (oxr->line == -1) ^ (xr->line == -1);
10352d11c96Sschwarze if (xr->line == -1)
10452d11c96Sschwarze oxr->line = -1;
10519b6bef7Sschwarze free(xr);
10652d11c96Sschwarze return ret;
10719b6bef7Sschwarze }
10819b6bef7Sschwarze
10919b6bef7Sschwarze struct mandoc_xr *
mandoc_xr_get(void)11019b6bef7Sschwarze mandoc_xr_get(void)
11119b6bef7Sschwarze {
11219b6bef7Sschwarze return xr_first;
11319b6bef7Sschwarze }
11419b6bef7Sschwarze
11519b6bef7Sschwarze void
mandoc_xr_free(void)11619b6bef7Sschwarze mandoc_xr_free(void)
11719b6bef7Sschwarze {
11819b6bef7Sschwarze mandoc_xr_clear();
11919b6bef7Sschwarze free(xr_hash);
12019b6bef7Sschwarze xr_hash = NULL;
12119b6bef7Sschwarze }
122