#include "openaxiom-c-macros.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#define WCT
#include "edible.h"
#define MAX_PREFIX 1024
#define strneql(a,b,n) (*(a) == *(b) && !strncmp((a),(b),(n)))
#define Delimiter(c) (! isalnum(c) && c != '%' && c != '!' && c != '?' && c != '_')
#include "wct.h"
#include "prt.h"
#include "edin.h"
static Wct *pwct = 0;
static Wix *pwix;
static Wix curr_wix;
static char curr_prefix[MAX_PREFIX];
static Wct *pHeadwct;
time_t
ftime(char *path)
{
int rc;
struct stat stbuf;
rc = stat(path, &stbuf);
if (rc == -1)
fatal("Cannot deterimine status of %s.", path);
return stbuf.st_mtime;
}
off_t
fsize(char *path)
{
int rc;
struct stat stbuf;
rc = stat(path, &stbuf);
if (rc == -1)
fatal("Cannot deterimine status of %s.", path);
return stbuf.st_size;
}
Wix *
scanWct(Wct *pwct, char *prefix)
{
long fmod;
int preflen, i, wc;
char **wv;
preflen = strlen(prefix);
strncpy(curr_prefix, prefix, MAX_PREFIX);
pHeadwct = pwct;
curr_wix.pwct = 0;
curr_wix.word = 0;
for (; pwct; pwct = pwct->next) {
curr_wix.pwct = pwct;
fmod = ftime(pwct->fname);
if (fmod > pwct->ftime)
reintern1Wct(pwct);
wv = pwct->wordv;
wc = pwct->wordc;
for (i = 0; i < wc; i++) {
curr_wix.word = i;
if (strneql(wv[i], prefix, preflen))
return &curr_wix;
}
}
return 0;
}
Wix *
rescanWct(void)
{
Wct *pwct, *start_pwct;
int preflen, start_word, i, wc;
char **wv, *prefix;
start_pwct = curr_wix.pwct;
start_word = curr_wix.word;
if (!start_pwct) return(0);
prefix = curr_prefix;
preflen = strlen(prefix);
pwct = start_pwct;
curr_wix.pwct = pwct;
wv = pwct->wordv;
wc = pwct->wordc;
for (i = start_word + 1; i < wc; i++) {
curr_wix.word = i;
if (strneql(wv[i], prefix, preflen))
return &curr_wix;
}
for (pwct = pwct->next; pwct; pwct = pwct->next) {
curr_wix.pwct = pwct;
wv = pwct->wordv;
wc = pwct->wordc;
for (i = 0; i < wc; i++) {
curr_wix.word = i;
if (strneql(wv[i], prefix, preflen))
return &curr_wix;
}
}
for (pwct = pHeadwct; pwct != start_pwct; pwct = pwct->next) {
curr_wix.pwct = pwct;
wv = pwct->wordv;
wc = pwct->wordc;
for (i = 0; i < wc; i++) {
curr_wix.word = i;
if (strneql(wv[i], prefix, preflen))
return &curr_wix;
}
}
curr_wix.pwct = pwct;
wv = pwct->wordv;
wc = pwct->wordc;
for (i = 0; i <= start_word; i++) {
curr_wix.word = i;
if (strneql(wv[i], prefix, preflen))
return &curr_wix;
}
return 0;
}
void
skimWct(Wct *pwct)
{
while (pwct) {
#ifdef PINFO
skim1Wct(pwct);
#endif
pwct = pwct->next;
}
}
void
skim1Wct(Wct *pwct)
{
#define NHEAD 13
#define NTAIL 7
int cc;
printf("%-10s", pwct->fname);
printTime((long *)&(pwct->ftime));
cc = skimString(pwct->fimage, pwct->fsize, NHEAD, NTAIL);
printf("%s", " " + (cc - (NHEAD + NTAIL)));
printf(" [%d w, %ld c]", pwct->wordc, (long)(pwct->fsize));
printf("\n");
#ifdef SHOW_WORDS
{
int i;
char **wv;
for (i = 1, wv = pwct->wordv; *wv; i++, wv++) {
printf("%5d: %s\n", i, *wv);
}
}
#endif
}
void
printTime(long *clock)
{
struct tm *tm;
tm = localtime((time_t *)clock);
printf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d ",
tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
int
skimString(char *s, int slen,int nhead,int ntail)
{
int spos, tlen, i, cc;
cc = printf("\"");
for (spos = 0; spos < slen && cc <= nhead; spos++)
cc += prChar(s[spos]);
tlen = ntail * ((1.0 * spos) / nhead);
if (spos + tlen >= slen)
for (; spos < slen; spos++)
cc += prChar(s[spos]);
else {
cc += printf("\"...\"");
for (i = slen - tlen; i < slen; i++)
cc += prChar(s[i]);
}
cc += printf("\"");
return cc;
}
int
prChar(int c)
{
if (c == '\n')
return printf("\\n");
if (c == '\t')
return printf("\\t");
if (c == '\b')
return printf("\\b");
if (c == '"')
return printf("\\\"");
if (iscntrl(c))
return printf("^%c", (c + 0100) % 0200);
if (isascii(c))
return printf("%c", c);
return printf("\\%d", c);
}
Wct *
reread1Wct(Wct *pwct)
{
int fd, rc;
pwct->fsize = fsize(pwct->fname);
pwct->ftime = ftime(pwct->fname);
if (pwct->fimage)
free(pwct->fimage);
pwct->fimage = (char *) malloc(pwct->fsize + 1);
if (pwct->fimage == 0)
sfatal("Cannot allocate new table.");
pwct->fimage[pwct->fsize] = 0;
fd = open(pwct->fname, O_RDONLY);
if (fd == -1)
fatal("Cannot read file %s.", pwct->fname);
rc = read(fd, pwct->fimage, pwct->fsize);
if (rc != pwct->fsize)
fatal("Did not read all of file %s.", pwct->fname);
return pwct;
}
Wct *
read1Wct(char *fname)
{
Wct *pwct;
pwct = (Wct *) malloc(sizeof(Wct));
if (pwct == 0)
sfatal("Cannot allocate new table.");
pwct->fname = fname;
pwct->wordc = 0;
pwct->wordv = 0;
pwct->fimage = 0;
pwct->next = 0;
return reread1Wct(pwct);
}
Wct *
nconcWct(Wct *pwct,Wct * qwct)
{
Wct *p0 = pwct;
if (!p0)
return qwct;
while (pwct->next)
pwct = pwct->next;
pwct->next = qwct;
return p0;
}
void
sortWct(Wct *pwct)
{
while (pwct) {
sort1Wct(pwct);
pwct = pwct->next;
}
}
void
sort1Wct(Wct *pwct)
{
qsort((char *) pwct->wordv, pwct->wordc,
sizeof(*(pwct->wordv)), mystrcmp);
}
int
mystrcmp(const void *s1,const void * s2)
{
return strcmp(*(char **)s1, *(char **)s2);
}
void
burstWct(Wct *pwct)
{
while (pwct) {
burst1Wct(pwct);
pwct = pwct->next;
}
}
void
burst1Wct(Wct *pwct)
{
char *s, **wv;
int i, j, inword = 0;
for (s = pwct->fimage, i = 0; i < pwct->fsize; s++, i++) {
if (isspace(*s) || iscntrl(*s)) {
*s = 0;
inword = 0;
}
else if (!inword) {
inword = 1;
pwct->wordc++;
}
}
if (pwct->wordv)
free(pwct->wordv);
pwct->wordv = (char **) calloc(pwct->wordc + 1, sizeof(char *));
if (!pwct->wordv)
fatal("Could not make word list for %s.", pwct->fname);
s = pwct->fimage;
i = 0;
for (wv = pwct->wordv, j = 0; j < pwct->wordc; wv++, j++) {
while (i < pwct->fsize && !s[i])
i++;
*wv = s + i;
while (i < pwct->fsize && s[i])
i++;
}
*wv = 0;
}
Wct *
intern1Wct(char *fname)
{
Wct *pwct;
pwct = read1Wct(fname);
burst1Wct(pwct);
return pwct;
}
void
reintern1Wct(Wct *pwct)
{
reread1Wct(pwct);
burst1Wct(pwct);
}
void
sfatal(const char *s)
{
fatal("%s", s);
}
void
fatal(const char* fmt, const char* s)
{
static char fbuf[256];
sprintf(fbuf, fmt, s);
perror(fbuf);
exit(1);
}
void
load_wct_file(char *fname)
{
pwct = nconcWct(intern1Wct(fname), pwct);
}
void
skim_wct(void)
{
skimWct(pwct);
}
void
rescan_wct(void)
{
int b = curr_pntr - 1;
int old_len;
int new_len;
int diff;
int i;
int ncs = 0;
while (b && !Delimiter(buff[b]))
b--;
if (Delimiter(buff[b]))
b++;
old_len = curr_pntr - b;
pwix = rescanWct();
if (!pwix) {
putchar(_BELL);
fflush(stdout);
}
else {
Wct *pwct = pwix->pwct;
new_len = strlen(pwct->wordv[pwix->word]);
if (new_len > old_len) {
diff = new_len - old_len;
if (curr_pntr != buff_pntr) {
forwardcopy(&buff[curr_pntr + diff],
&buff[curr_pntr],
buff_pntr - curr_pntr);
forwardflag_cpy(&buff_flag[curr_pntr + diff],
&buff_flag[curr_pntr],
buff_pntr - curr_pntr);
}
buff_pntr += diff;
ncs = curr_pntr + diff;
for (i = 0; i < new_len; i++)
buff[b + i] = (pwct->wordv[pwix->word])[i];
for (; curr_pntr != b; curr_pntr--)
putchar(_BKSPC);
printbuff(curr_pntr, buff_pntr - curr_pntr);
for (i = buff_pntr; i != ncs; i--)
putchar(_BKSPC);
fflush(stdout);
curr_pntr = ncs;
}
else if (new_len < old_len) {
diff = old_len - new_len;
strncpy(&buff[curr_pntr - diff],
&buff[curr_pntr],
buff_pntr - curr_pntr);
flagncpy(&buff_flag[curr_pntr - diff],
&buff_flag[curr_pntr],
buff_pntr - curr_pntr);
buff_pntr -= diff;
ncs = curr_pntr - diff;
for (i = 0; i < new_len; i++)
buff[b + i] = (pwct->wordv[pwix->word])[i];
for (; curr_pntr != b; curr_pntr--)
putchar(_BKSPC);
printbuff(b, buff_pntr - b);
for (i = 0; i < diff; i++)
myputchar(' ');
for (i = buff_pntr + diff; i != ncs; i--)
putchar(_BKSPC);
fflush(stdout);
curr_pntr = ncs;
}
else {
diff = 0;
ncs = curr_pntr;
for (i = 0; i < new_len; i++)
buff[b + i] = (pwct->wordv[pwix->word])[i];
for (; curr_pntr != b; curr_pntr--)
putchar(_BKSPC);
printbuff(curr_pntr, buff_pntr - curr_pntr);
for (i = buff_pntr; i != ncs; i--)
putchar(_BKSPC);
fflush(stdout);
curr_pntr = ncs;
}
}
}
void
find_wct(void)
{
char search_buff[100];
char *filler = search_buff;
int b = curr_pntr - 1;
int e = curr_pntr;
int ne = 0;
int st;
Wix *pwix;
int curr_len;
int new_len;
int diff;
int i;
if (!curr_pntr) {
putchar(_BELL);
return;
}
while (b && !Delimiter(buff[b]))
b--;
if (Delimiter(buff[b]))
b++;
while (e < buff_pntr && !Delimiter(buff[e])) {
e++;
ne++;
}
st = b;
curr_len = e - b;
while (b < curr_pntr)
*filler++ = buff[b++];
*filler = '\0';
pwix = scanWct(pwct, search_buff);
if (!pwix) {
putchar(_BELL);
fflush(stdout);
}
else {
Wct *pwct = pwix->pwct;
new_len = strlen(pwct->wordv[pwix->word]);
diff = new_len - curr_len;
if (curr_pntr != buff_pntr) {
forwardcopy(&buff[curr_pntr + diff],
&buff[curr_pntr],
buff_pntr - curr_pntr);
forwardflag_cpy(&buff_flag[curr_pntr + diff],
&buff_flag[curr_pntr],
buff_pntr - curr_pntr);
}
buff_pntr += diff;
for (i = new_len - diff; i < new_len; i++)
buff[st + i] = (pwct->wordv[pwix->word])[i];
for (i = 0; i < diff; i++)
putchar(buff[curr_pntr++]);
printbuff(curr_pntr, buff_pntr - curr_pntr);
for (i = buff_pntr; i != e + diff; i--)
putchar(_BKSPC);
fflush(stdout);
curr_pntr = diff + e;
}
}