aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tag.c
diff options
context:
space:
mode:
Diffstat (limited to 'tag.c')
-rw-r--r--tag.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/tag.c b/tag.c
index c0832c4f..823f2045 100644
--- a/tag.c
+++ b/tag.c
@@ -1,6 +1,6 @@
-/* $Id: tag.c,v 1.19 2018/02/23 16:47:10 schwarze Exp $ */
+/* $Id: tag.c,v 1.20 2018/10/23 20:42:37 schwarze Exp $ */
/*
- * Copyright (c) 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2015, 2016, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,6 +18,7 @@
#include <sys/types.h>
+#include <limits.h>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
@@ -121,41 +122,57 @@ fail:
/*
* Set the line number where a term is defined,
- * unless it is already defined at a higher priority.
+ * unless it is already defined at a lower priority.
*/
void
tag_put(const char *s, int prio, size_t line)
{
struct tag_entry *entry;
+ const char *se;
size_t len;
unsigned int slot;
- /* Sanity checks. */
-
if (tag_files.tfd <= 0)
return;
+
if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e'))
s += 2;
- if (*s == '\0' || strchr(s, ' ') != NULL)
+
+ /*
+ * Skip whitespace and whatever follows it,
+ * and if there is any, downgrade the priority.
+ */
+
+ len = strcspn(s, " \t");
+ if (len == 0)
return;
- slot = ohash_qlookup(&tag_data, s);
+ se = s + len;
+ if (*se != '\0')
+ prio = INT_MAX;
+
+ slot = ohash_qlookupi(&tag_data, s, &se);
entry = ohash_find(&tag_data, slot);
if (entry == NULL) {
/* Build a new entry. */
- len = strlen(s) + 1;
- entry = mandoc_malloc(sizeof(*entry) + len);
+ entry = mandoc_malloc(sizeof(*entry) + len + 1);
memcpy(entry->s, s, len);
+ entry->s[len] = '\0';
entry->lines = NULL;
entry->maxlines = entry->nlines = 0;
ohash_insert(&tag_data, slot, entry);
} else {
- /* Handle priority 0 entries. */
+ /*
+ * Lower priority numbers take precedence,
+ * but 0 is special.
+ * A tag with priority 0 is only used
+ * if the tag occurs exactly once.
+ */
if (prio == 0) {
if (entry->prio == 0)