summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.c1
-rw-r--r--tags.c49
2 files changed, 47 insertions, 3 deletions
diff --git a/build.c b/build.c
index 4a65857..72cc59c 100644
--- a/build.c
+++ b/build.c
@@ -22,6 +22,7 @@ static void build_start_with_command(Ted *ted, char const *command) {
if (ted->building) {
build_stop(ted);
}
+ build_clear(ted); // clear errors from previous build
ted_save_all(ted);
if (process_run(&ted->build_process, command)) {
diff --git a/tags.c b/tags.c
index 119a510..efe70f8 100644
--- a/tags.c
+++ b/tags.c
@@ -41,6 +41,49 @@ static int tag_try(FILE *fp, char const *tag) {
return -1;
}
+// finds all tags beginning with the given prefix, returning them into *out, writing at most out_size entries.
+// each element in out should be freed when you're done with them
+size_t tags_beginning_with(Ted *ted, char const *prefix, char **out, size_t out_size) {
+ assert(out_size);
+
+ FILE *file = fopen(tags_filename(ted), "rb");
+ if (!file) return false;
+
+ fseek(file, 0, SEEK_END);
+ size_t file_size = (size_t)ftell(file);
+ // binary search for prefix in file
+ size_t lo = 0;
+ size_t hi = file_size;
+ size_t mid = 0;
+ bool exact = false;
+ while (lo < hi) {
+ mid = (lo + hi) / 2;
+ fseek(file, (long)mid, SEEK_SET);
+ int cmp = tag_try(file, prefix);
+ if (cmp > 0) {
+ lo = mid + 1;
+ } else if (cmp < 0) {
+ hi = mid;
+ } else {
+ exact = true;
+ break;
+ }
+ }
+ char line[1024];
+ if (!exact)
+ fgets(line, sizeof line, file); // go to next line
+
+ size_t nmatches = 0;
+ while (fgets(line, sizeof line, file)) {
+ if (str_is_prefix(line, prefix)) {
+ out[nmatches++] = strn_dup(line, strcspn(line, "\t"));
+ if (nmatches >= out_size) break;
+ } else break;
+ }
+ fclose(file);
+ return nmatches;
+}
+
// returns true if the tag exists.
bool tag_goto(Ted *ted, char const *tag) {
char const *tags_name = tags_filename(ted);
@@ -64,15 +107,15 @@ bool tag_goto(Ted *ted, char const *tag) {
hi = mid;
} else {
// we found it!
- char tag_enty[1024];
- if (fgets(tag_enty, sizeof tag_enty, file)) {
+ char tag_entry[1024];
+ if (fgets(tag_entry, sizeof tag_entry, file)) {
// the tag is of the format:
// tag name\tfile name\taddress
// or
// tag name\tfile name\taddress;" additional information
- char *name = tag_enty;
+ char *name = tag_entry;
char *name_end = strchr(name, '\t');
if (name_end) {
*name_end = '\0';