-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathtag.c
94 lines (87 loc) · 1.68 KB
/
tag.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "vi.h"
static char *tagpath;
static char *tag;
static long taglen;
int tag_init(void)
{
return 0;
}
static int tag_load(void)
{
char buf[1 << 10];
struct sbuf *sb;
long nr;
int fd;
if (tagpath != NULL)
return tag == NULL;
tagpath = getenv("TAGPATH") ? getenv("TAGPATH") : "tags";
if ((fd = open(tagpath, O_RDONLY)) < 0)
return 1;
sb = sbuf_make();
while ((nr = read(fd, buf, sizeof(buf))) > 0)
sbuf_mem(sb, buf, nr);
close(fd);
taglen = sbuf_len(sb);
tag = sbuf_done(sb);
return 0;
}
void tag_done(void)
{
free(tag);
tag = NULL;
tagpath = NULL;
}
static char *copypart(char *dst, int dstlen, char *src)
{
char *end = src;
int len = dstlen - 1;
while (*end && *end != '\t' && *end != '\n')
end++;
if (end - src < len)
len = end - src;
if (dst != NULL && dstlen > 0) {
memcpy(dst, src, len);
dst[len] = '\0';
}
return *end ? end + 1 : end;
}
static char *tag_next(char *s, int dir)
{
if (dir >= 0 && *s) {
if ((s = strchr(s + 1, '\n')) != NULL)
return s + 1;
}
if (dir < 0 && s > tag) {
s--;
while (s > tag && s[-1] != '\n')
s--;
return s;
}
return NULL;
}
int tag_find(char *name, int *pos, int dir, char *path, int pathlen, char *cmd, int cmdlen)
{
char *s;
int len = strlen(name);
if (tag_load() != 0)
return 1;
if (*pos >= taglen)
*pos = 0;
s = dir != 0 ? tag_next(tag + *pos, dir) : tag + *pos;
while (s) {
if (!strncmp(name, s, len) && s[len] == '\t') {
char *r = copypart(path, pathlen, s + len + 1);
copypart(cmd, cmdlen, r);
*pos = s - tag;
return 0;
}
s = tag_next(s, dir);
}
return 1;
}