version 1.23, 2019/07/19 20:27:25 |
version 1.27, 2020/01/20 10:37:15 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2015, 2016, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
|
#include <assert.h> |
#include <errno.h> |
#include <errno.h> |
#include <limits.h> |
#include <limits.h> |
#include <signal.h> |
#include <signal.h> |
Line 53 static struct tag_files tag_files; |
|
Line 54 static struct tag_files tag_files; |
|
* but for simplicity, create it anyway. |
* but for simplicity, create it anyway. |
*/ |
*/ |
struct tag_files * |
struct tag_files * |
tag_init(void) |
tag_init(char *tagname) |
{ |
{ |
struct sigaction sa; |
struct sigaction sa; |
int ofd; |
int ofd; |
|
|
ofd = -1; |
ofd = -1; |
tag_files.tfd = -1; |
tag_files.tfd = -1; |
tag_files.tcpgid = -1; |
tag_files.tcpgid = -1; |
|
tag_files.tagname = tagname; |
|
|
/* Clean up when dying from a signal. */ |
/* Clean up when dying from a signal. */ |
|
|
|
|
*tag_files.tfn = '\0'; |
*tag_files.tfn = '\0'; |
tag_files.ofd = -1; |
tag_files.ofd = -1; |
tag_files.tfd = -1; |
tag_files.tfd = -1; |
|
tag_files.tagname = NULL; |
return NULL; |
return NULL; |
} |
} |
|
|
Line 144 tag_put(const char *s, int prio, size_t line) |
|
Line 147 tag_put(const char *s, int prio, size_t line) |
|
size_t len; |
size_t len; |
unsigned int slot; |
unsigned int slot; |
|
|
|
assert(prio <= TAG_FALLBACK); |
if (tag_files.tfd <= 0) |
if (tag_files.tfd <= 0) |
return; |
return; |
|
|
Line 151 tag_put(const char *s, int prio, size_t line) |
|
Line 155 tag_put(const char *s, int prio, size_t line) |
|
s += 2; |
s += 2; |
|
|
/* |
/* |
* Skip whitespace and whatever follows it, |
* Skip whitespace and escapes and whatever follows, |
* and if there is any, downgrade the priority. |
* and if there is any, downgrade the priority. |
*/ |
*/ |
|
|
len = strcspn(s, " \t"); |
len = strcspn(s, " \t\\"); |
if (len == 0) |
if (len == 0) |
return; |
return; |
|
|
se = s + len; |
se = s + len; |
if (*se != '\0') |
if (*se != '\0' && prio < TAG_WEAK) |
prio = INT_MAX; |
prio = TAG_WEAK; |
|
|
slot = ohash_qlookupi(&tag_data, s, &se); |
slot = ohash_qlookupi(&tag_data, s, &se); |
entry = ohash_find(&tag_data, slot); |
entry = ohash_find(&tag_data, slot); |
Line 181 tag_put(const char *s, int prio, size_t line) |
|
Line 185 tag_put(const char *s, int prio, size_t line) |
|
|
|
/* |
/* |
* Lower priority numbers take precedence, |
* Lower priority numbers take precedence, |
* but 0 is special. |
* but TAG_FALLBACK is special. |
* A tag with priority 0 is only used |
* A tag with priority TAG_FALLBACK is only used |
* if the tag occurs exactly once. |
* if the tag occurs exactly once. |
*/ |
*/ |
|
|
if (prio == 0) { |
if (prio == TAG_FALLBACK) { |
if (entry->prio == 0) |
if (entry->prio == TAG_FALLBACK) |
entry->prio = -1; |
entry->prio = TAG_DELETE; |
return; |
return; |
} |
} |
|
|
/* A better entry is already present, ignore the new one. */ |
/* A better entry is already present, ignore the new one. */ |
|
|
if (entry->prio > 0 && entry->prio < prio) |
if (entry->prio < prio) |
return; |
return; |
|
|
/* The existing entry is worse, clear it. */ |
/* The existing entry is worse, clear it. */ |
|
|
if (entry->prio < 1 || entry->prio > prio) |
if (entry->prio > prio) |
entry->nlines = 0; |
entry->nlines = 0; |
} |
} |
|
|
|
|
empty = 1; |
empty = 1; |
entry = ohash_first(&tag_data, &slot); |
entry = ohash_first(&tag_data, &slot); |
while (entry != NULL) { |
while (entry != NULL) { |
if (stream != NULL && entry->prio >= 0) { |
if (stream != NULL && entry->prio < TAG_DELETE) { |
for (i = 0; i < entry->nlines; i++) { |
for (i = 0; i < entry->nlines; i++) { |
fprintf(stream, "%s %s %zu\n", |
fprintf(stream, "%s %s %zu\n", |
entry->s, tag_files.ofn, entry->lines[i]); |
entry->s, tag_files.ofn, entry->lines[i]); |