version 1.1, 2009/09/17 07:41:28 |
version 1.2, 2009/09/17 08:21:42 |
|
|
|
|
#include "chars.h" |
#include "chars.h" |
|
|
#define ASCII_PRINT_HI 126 |
#define PRINT_HI 126 |
#define ASCII_PRINT_LO 32 |
#define PRINT_LO 32 |
|
|
struct ln { |
struct ln { |
struct ln *next; |
struct ln *next; |
const char *code; |
const char *code; |
const char *out; |
const char *ascii; |
|
const char *html; |
size_t codesz; |
size_t codesz; |
size_t outsz; |
size_t asciisz; |
|
size_t htmlsz; |
int type; |
int type; |
#define CHARS_CHAR (1 << 0) |
#define CHARS_CHAR (1 << 0) |
#define CHARS_STRING (1 << 1) |
#define CHARS_STRING (1 << 1) |
|
|
|
|
#define LINES_MAX 266 |
#define LINES_MAX 266 |
|
|
#define CHAR(w, x, y, z) \ |
#define CHAR(w, x, y, z, a, b) \ |
{ NULL, (w), (y), (x), (z), CHARS_CHAR }, |
{ NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR }, |
#define STRING(w, x, y, z) \ |
#define STRING(w, x, y, z, a, b) \ |
{ NULL, (w), (y), (x), (z), CHARS_STRING }, |
{ NULL, (w), (y), (a), (x), (z), (b), CHARS_STRING }, |
#define BOTH(w, x, y, z) \ |
#define BOTH(w, x, y, z, a, b) \ |
{ NULL, (w), (y), (x), (z), CHARS_BOTH }, |
{ NULL, (w), (y), (a), (x), (z), (b), CHARS_BOTH }, |
|
|
static struct ln lines[LINES_MAX] = { |
static struct ln lines[LINES_MAX] = { |
#include "chars.in" |
#include "chars.in" |
}; |
}; |
|
|
struct tbl { |
struct tbl { |
|
enum chars type; |
struct ln **htab; |
struct ln **htab; |
}; |
}; |
|
|
Line 71 chars_free(void *arg) |
|
Line 74 chars_free(void *arg) |
|
} |
} |
|
|
|
|
/* ARGSUSED */ |
|
void * |
void * |
chars_init(enum chars type) |
chars_init(enum chars type) |
{ |
{ |
Line 89 chars_init(enum chars type) |
|
Line 91 chars_init(enum chars type) |
|
|
|
if (NULL == (tab = malloc(sizeof(struct tbl)))) |
if (NULL == (tab = malloc(sizeof(struct tbl)))) |
err(1, "malloc"); |
err(1, "malloc"); |
|
tab->type = type; |
|
|
htab = calloc(ASCII_PRINT_HI - ASCII_PRINT_LO + 1, |
htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **)); |
sizeof(struct ln **)); |
|
|
|
if (NULL == htab) |
if (NULL == htab) |
err(1, "malloc"); |
err(1, "malloc"); |
|
|
for (i = 0; i < LINES_MAX; i++) { |
for (i = 0; i < LINES_MAX; i++) { |
assert(lines[i].codesz > 0); |
hash = (int)lines[i].code[0] - PRINT_LO; |
assert(lines[i].code); |
|
assert(lines[i].out); |
|
|
|
hash = (int)lines[i].code[0] - ASCII_PRINT_LO; |
|
|
|
if (NULL == (pp = htab[hash])) { |
if (NULL == (pp = htab[hash])) { |
htab[hash] = &lines[i]; |
htab[hash] = &lines[i]; |
continue; |
continue; |
Line 110 chars_init(enum chars type) |
|
Line 107 chars_init(enum chars type) |
|
|
|
for ( ; pp->next; pp = pp->next) |
for ( ; pp->next; pp = pp->next) |
/* Scan ahead. */ ; |
/* Scan ahead. */ ; |
|
|
pp->next = &lines[i]; |
pp->next = &lines[i]; |
} |
} |
|
|
Line 145 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
Line 141 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
assert(p); |
assert(p); |
assert(sz > 0); |
assert(sz > 0); |
|
|
if (p[0] < ASCII_PRINT_LO || p[0] > ASCII_PRINT_HI) |
if (p[0] < PRINT_LO || p[0] > PRINT_HI) |
return(NULL); |
return(NULL); |
|
|
/* |
/* |
Line 154 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
Line 150 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
* to optimise for repeat hits. |
* to optimise for repeat hits. |
*/ |
*/ |
|
|
hash = (int)p[0] - ASCII_PRINT_LO; |
hash = (int)p[0] - PRINT_LO; |
htab = tab->htab; |
htab = tab->htab; |
|
|
if (NULL == (pp = htab[hash])) |
if (NULL == (pp = htab[hash])) |
Line 163 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
Line 159 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
if (NULL == pp->next) { |
if (NULL == pp->next) { |
if ( ! match(pp, p, sz, type)) |
if ( ! match(pp, p, sz, type)) |
return(NULL); |
return(NULL); |
*rsz = pp->outsz; |
|
return(pp->out); |
if (CHARS_HTML == tab->type) { |
|
*rsz = pp->htmlsz; |
|
return(pp->html); |
|
} |
|
*rsz = pp->asciisz; |
|
return(pp->ascii); |
} |
} |
|
|
for (prev = NULL; pp; pp = pp->next) { |
for (prev = NULL; pp; pp = pp->next) { |
Line 173 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
Line 174 find(struct tbl *tab, const char *p, size_t sz, size_t |
|
continue; |
continue; |
} |
} |
|
|
/* Re-order the hash chain. */ |
|
|
|
if (prev) { |
if (prev) { |
prev->next = pp->next; |
prev->next = pp->next; |
pp->next = htab[hash]; |
pp->next = htab[hash]; |
htab[hash] = pp; |
htab[hash] = pp; |
} |
} |
|
|
*rsz = pp->outsz; |
if (CHARS_HTML == tab->type) { |
return(pp->out); |
*rsz = pp->htmlsz; |
|
return(pp->html); |
|
} |
|
*rsz = pp->asciisz; |
|
return(pp->ascii); |
} |
} |
|
|
return(NULL); |
return(NULL); |