mirror of
https://github.com/johnkerl/miller.git
synced 2026-01-23 02:14:13 +00:00
94 lines
2.7 KiB
C
94 lines
2.7 KiB
C
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include "lib/mlrutil.h"
|
|
#include "containers/parse_trie.h"
|
|
|
|
static parse_trie_node_t* parse_trie_node_alloc(char c);
|
|
static void parse_trie_print_aux(parse_trie_node_t* pnode, int depth);
|
|
static void parse_trie_add_string_aux(parse_trie_node_t* pnode, char* string, int stridx, int len);
|
|
|
|
// ----------------------------------------------------------------
|
|
parse_trie_t* parse_trie_alloc() {
|
|
parse_trie_t* ptrie = mlr_malloc_or_die(sizeof(parse_trie_t));
|
|
ptrie->past = parse_trie_node_alloc(0);
|
|
ptrie->maxlen = 0;
|
|
return ptrie;
|
|
}
|
|
|
|
static parse_trie_node_t* parse_trie_node_alloc(char c) {
|
|
parse_trie_node_t* pnode = mlr_malloc_or_die(sizeof(parse_trie_node_t));
|
|
for (int i = 0; i < 256; i++)
|
|
pnode->pnexts[i] = NULL;
|
|
pnode->c = c;
|
|
pnode->stridx = -1;
|
|
pnode->strlen = -1;
|
|
return pnode;
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
static void parse_trie_free_node_descendants(parse_trie_node_t* pnode) {
|
|
for (int i = 0; i < 256; i++) {
|
|
parse_trie_node_t* pnext = pnode->pnexts[i];
|
|
if (pnext != NULL) {
|
|
parse_trie_free_node_descendants(pnext);
|
|
free(pnext);
|
|
}
|
|
}
|
|
}
|
|
|
|
void parse_trie_free(parse_trie_t* ptrie) {
|
|
parse_trie_free_node_descendants(ptrie->past);
|
|
free(ptrie->past);
|
|
free(ptrie);
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
void parse_trie_print(parse_trie_t* ptrie) {
|
|
parse_trie_node_t* pnode = ptrie->past;
|
|
printf("PARSE TRIE DUMP START\n");
|
|
if (pnode != NULL) {
|
|
parse_trie_print_aux(pnode, 0);
|
|
}
|
|
printf("PARSE TRIE DUMP END\n");
|
|
}
|
|
|
|
static void parse_trie_print_aux(parse_trie_node_t* pnode, int depth) {
|
|
for (int i = 0; i < depth; i++)
|
|
printf(" ");
|
|
printf("c=%c[%02x],stridx=%d,strlen=%d\n",
|
|
isprint((unsigned char)pnode->c) ? pnode->c : '?',
|
|
(unsigned)pnode->c,
|
|
pnode->stridx,
|
|
pnode->strlen);
|
|
for (int i = 0; i < 256; i++) {
|
|
parse_trie_node_t* pnext = pnode->pnexts[i];
|
|
if (pnext != NULL)
|
|
parse_trie_print_aux(pnext, depth+1);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------
|
|
void parse_trie_add_string(parse_trie_t* ptrie, char* string, int stridx) {
|
|
int len = strlen(string);
|
|
parse_trie_add_string_aux(ptrie->past, string, stridx, strlen(string));
|
|
if (len > ptrie->maxlen)
|
|
ptrie->maxlen = len;
|
|
}
|
|
|
|
static void parse_trie_add_string_aux(parse_trie_node_t* pnode, char* string, int stridx, int len) {
|
|
char c = string[0];
|
|
if (c == 0) {
|
|
pnode->stridx = stridx;
|
|
pnode->strlen = len;
|
|
} else {
|
|
parse_trie_node_t* pnext = pnode->pnexts[(unsigned char)c];
|
|
if (pnext == NULL) {
|
|
pnext = parse_trie_node_alloc(c);
|
|
pnext->c = c;
|
|
pnext->stridx = -1;
|
|
pnext->strlen = -1;
|
|
pnode->pnexts[(unsigned char)c] = pnext;
|
|
}
|
|
parse_trie_add_string_aux(pnext, &string[1], stridx, len);
|
|
}
|
|
}
|