Skip to content

Commit

Permalink
a simple small cli tool
Browse files Browse the repository at this point in the history
  • Loading branch information
Conni2461 committed Feb 19, 2022
1 parent 8ec164b commit 0de8b50
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ else
TARGET := libfzf.so
endif

all: build/$(TARGET)
all: build/$(TARGET) build/cli

build/cli: src/fzf.c src/fzf.h src/cli.c
$(MKD) build
$(CC) -Ofast -Wall -Werror src/fzf.c src/cli.c -o build/cli

build/$(TARGET): src/fzf.c src/fzf.h
$(MKD) build
Expand Down
130 changes: 130 additions & 0 deletions src/cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include "fzf.h"

// sorting
typedef struct {
char *str;
int32_t score;
size_t len;
} fzf_tuple_t;

typedef struct {
fzf_tuple_t *data;
size_t len;
size_t cap;
} heap_t;

heap_t *new_heap() {
heap_t *res = (heap_t *)malloc(sizeof(heap_t));
res->cap = 512;
res->data = malloc(sizeof(fzf_tuple_t) * res->cap);
res->len = 0;
return res;
}

void free_heap(heap_t *heap) {
free(heap->data);
free(heap);
}

static size_t parent(size_t i) {
return (i - 1) / 2;
}

static size_t left_child(size_t i) {
return 2 * i + 1;
}

static size_t right_child(size_t i) {
return 2 * i + 2;
}

void swap(fzf_tuple_t *x, fzf_tuple_t *y) {
fzf_tuple_t temp = *x;
*x = *y;
*y = temp;
}

static bool smaller(fzf_tuple_t *lhs, fzf_tuple_t *rhs) {
return (lhs->score == rhs->score && lhs->len > rhs->len) ||
lhs->score < rhs->score;
}

bool greater(fzf_tuple_t *lhs, fzf_tuple_t *rhs) {
return (lhs->score == rhs->score && lhs->len < rhs->len) ||
lhs->score > rhs->score;
}

static void insert(heap_t *heap, fzf_tuple_t data) {
if (heap->len >= heap->cap) {
heap->cap *= 2;
heap->data = realloc(heap->data, sizeof(fzf_tuple_t) * heap->cap);
}
size_t i = heap->len;
heap->data[heap->len++] = data;
while (i != 0 && smaller(&heap->data[parent(i)], &heap->data[i])) {
swap(&heap->data[parent(i)], &heap->data[i]);
i = parent(i);
}
}

static void max_heapify(heap_t *heap, size_t i) {
size_t left = left_child(i);
size_t right = right_child(i);
size_t largest = i;

if (left <= heap->len && greater(&heap->data[left], &heap->data[largest])) {
largest = left;
}

if (right <= heap->len && greater(&heap->data[right], &heap->data[largest])) {
largest = right;
}

if (largest != i) {
swap(&heap->data[i], &heap->data[largest]);
max_heapify(heap, largest);
}
}

static fzf_tuple_t extract_max(heap_t *heap) {
fzf_tuple_t max_item = heap->data[0];
heap->data[0] = heap->data[--heap->len];
max_heapify(heap, 0);
return max_item;
}

int main(int argc, char **argv) {
fzf_slab_t *slab = fzf_make_default_slab();
fzf_pattern_t *pattern = fzf_parse_pattern(CaseSmart, false, argv[1], true);
heap_t *heap = new_heap();

char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
line[read - 1] = '\0';
int32_t score = fzf_get_score(line, pattern, slab);
if (score > 0) {
char *copy = (char *)malloc(sizeof(char) * read);
strncpy(copy, line, read - 1);
copy[read - 1] = '\0';
insert(heap, (fzf_tuple_t){.str = copy, .score = score, .len = read - 1});
}
}

while (heap->len > 0) {
fzf_tuple_t el = extract_max(heap);
printf("%s\n", el.str);
free(el.str);
}
free_heap(heap);
fzf_free_pattern(pattern);
fzf_free_slab(slab);
free(line);
return 0;
}

0 comments on commit 0de8b50

Please sign in to comment.