1. Runt Word Search

This file implements a quick means to look up words using regex.

<<ws_c>>=
#include <stdio.h>
#include <runt.h>
#include <regex.h>

static char msgbuf[100];

static int compare(runt_vm *vm, regex_t *re, runt_entry *e, runt_int *cnt)
{
    const char *str;
    int rc;

    str = runt_to_string(e->p);

    rc = regexec(re, str, 0, NULL, 0);

    if(!rc) {
        runt_print(vm, "%s\n", str);
        *cnt = *cnt + 1;
    } else if(rc != REG_NOMATCH) {
        regerror(rc, re, msgbuf, sizeof(msgbuf));
        runt_print(vm, "%s\n", msgbuf);
        return RUNT_NOT_OK;
    }

    return RUNT_OK;
}

static runt_int rproc_ws(runt_vm *vm, runt_ptr p)
{
    const char *re;
    runt_stacklet *s;
    runt_int rc;
    int reti;
    int cnt;
    regex_t regex;
    runt_int w, e;
    runt_entry *entry;
    runt_dict *dict;
    runt_list *list;
    runt_int nentry;

    cnt = 0;
    nentry = 0;
    rc = runt_ppop(vm, &s);
    RUNT_ERROR_CHECK(rc);
    re = runt_to_string(s->p);

    reti =  regcomp(®ex, re, 0);

    if(reti) {
        runt_print(vm, "Could not compile regex\n");
        return RUNT_NOT_OK;
    }

    dict = runt_dictionary_get(vm);

    list = dict->list;
    for(w = 0; w < RUNT_DICT_SIZE; w++) {
        entry = runt_list_top(&list[w]);
        nentry = list[w].size;
        for(e = 0; e < nentry ; e++) {
            rc = compare(vm, ®ex, entry, &cnt);
            if(rc != RUNT_OK) return RUNT_NOT_OK;
            entry = entry->next;
        }
    }

    if(cnt == 0) {
        runt_print(vm, "Query returned no results.\n");
    } else if(cnt == 1) {
        runt_print(vm, "Query returned 1 result.\n");
    } else {
        runt_print(vm, "Query returned %d results.\n", cnt);
    }

    regfree(®ex);

    return RUNT_OK;
}

void load_ws(runt_vm *vm)
{
    runt_keyword_define(vm, "ws", 2, rproc_ws, NULL);
}