Files
TempleOS-Rijn/LT/Adam/WordStat/WSMain.APZ
T
2018-09-08 21:45:20 +02:00

767 lines
18 KiB
Plaintext

void WsPutMatrix(WsMatrix *m)
{
I8 i,j;
WsMatrixSide *ms;
WsStruct *tempw;
coutln "n:",m->n;
for (i=0;i<ws_num_matrix_words;i++) {
ms=&m->side[i];
coutln "col:",i," rhits:",ms->row_hits," chits:",ms->col_hits;
tempw=ms->next;
while (tempw!=ms) {
coutln " substructs:",tempw->substructs,
" entries:",tempw->entries;
for (j=0;j<tempw->substructs;j++) {
PrintF("(%04X %04X) ",
tempw->subs[j].hits,
tempw->subs[j].repeats);
}
CrLf;
tempw=tempw->next;
}
}
View;
}
WsHashEntry *WsAddHash(I1 *w)
{
WsHashEntry *tempw=FindHashEntry(w,ws_hash_table,HTT_WORD);
if (tempw) {
tempw->hits++;
return tempw;
}
tempw=AMAllocZ(sizeof(WsHashEntry));
tempw->word=ANewStr(w);
tempw->type=HTT_WORD;
tempw->use_cnt=1;
tempw->hits=1;
tempw->num=-1;
AddSysHashEntry(tempw,ws_hash_table);
ws_num_words++;
return tempw;
}
void WsInitSides(WsMatrix *m)
{
I8 i;
WsStruct *tempa;
m->n=0;
for (i=0;i<WS_MAX_MATRIX_WORDS;i++) {
m->side[i].next=&m->side[i].next;
m->side[i].last=&m->side[i].next;
m->side[i].const_minus_one=-1;
m->side[i].row_hits=0;
m->side[i].col_hits=0;
tempa=AMAlloc(sizeof(WsStruct));
tempa->subs[0].hits=0;
tempa->subs[0].repeats=ws_num_matrix_words;
tempa->entries=ws_num_matrix_words;
tempa->substructs=1;
InsQue(tempa,m->side[i].last);
}
}
WsStruct *WsFindStruct(WsMatrix *m,I8 col,I8 row,
I8 *row_base,I8 *substruct)
{
WsStruct *tempa;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return NULL;
if (row<ws_num_matrix_words>>1) {
tempa=m->side[col].next;
*row_base=0;
while (row>=tempa->entries) {
row-=tempa->entries;
*row_base+=tempa->entries;
tempa=tempa->next;
}
for (*substruct=0;row>=tempa->subs[*substruct].repeats;*substruct=*substruct+1) {
row-=tempa->subs[*substruct].repeats;
*row_base+=tempa->subs[*substruct].repeats;
}
} else {
row=ws_num_matrix_words-row;
tempa=m->side[col].last;
*row_base=ws_num_matrix_words;
while (row>tempa->entries) {
row-=tempa->entries;
*row_base-=tempa->entries;
tempa=tempa->last;
}
for (*substruct=tempa->substructs-1;row>tempa->subs[*substruct].repeats;
*substruct=*substruct-1) {
row-=tempa->subs[*substruct].repeats;
*row_base-=tempa->subs[*substruct].repeats;
}
*row_base-=tempa->subs[*substruct].repeats;
}
return tempa;
}
public I8 WsGetHits(WsMatrix *m,I8 col,I8 row)
{
I8 row_base,substruct;
WsStruct *tempa;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return 0;
tempa=WsFindStruct(m,col,row,
&row_base,&substruct);
return tempa->subs[substruct].hits;
}
WsSubstruct *WsNext(WsSubstruct *s,WsStruct **parent)
{
I8 i=(s-&(*parent)->subs)>>WS_SUBSTRUCT_SIZE_BITS+1;
if (i>=(*parent)->substructs) {
i=0;
*parent=(*parent)->next;
if ((*parent)->substructs==-1)
return NULL;
}
return &(*parent)->subs[i];
}
WsSubstruct *WsLast(WsSubstruct *s,WsStruct **parent)
{
I8 i=(s-&(*parent)->subs)>>WS_SUBSTRUCT_SIZE_BITS-1;
if (i<0) {
*parent=(*parent)->last;
if ((*parent)->substructs==-1)
return NULL;
i=(*parent)->substructs-1;
}
return &(*parent)->subs[i];
}
void WsRemove(WsSubstruct *s,WsStruct *parent)
{
I8 i=(s-&parent->subs)>>WS_SUBSTRUCT_SIZE_BITS;
if (i<0 || i>=WS_SUBSTRUCTS_PER_STRUCT || parent->substructs<1)
return;
if (parent->substructs==1) {
RemQue(parent);
AFree(parent);
} else {
parent->entries-=s->repeats;
parent->substructs--;
MemCpy(&parent->subs[i],&parent->subs[i+1],
(parent->substructs-i)*sizeof(WsSubstruct));
}
}
WsSubstruct *WsInsert(WsSubstruct *s,WsStruct **parent,WsSubstruct *last)
{
WsStruct *tempa,*p=*parent;
I8 j,k,i=(last-&p->subs)>>WS_SUBSTRUCT_SIZE_BITS+1;
if (i>=WS_SUBSTRUCTS_PER_STRUCT) {
i=0;
p=p->next;
*parent=p;
if (p->substructs==-1) {
tempa=AMAlloc(sizeof(WsStruct));
InsQue(tempa,p->last);
p=tempa;
*parent=p;
tempa->entries=0;
tempa->substructs=0;
}
}
if (p->substructs==WS_SUBSTRUCTS_PER_STRUCT) {
tempa=p->next;
if (tempa->substructs==-1 || tempa->substructs==WS_SUBSTRUCTS_PER_STRUCT) {
tempa=AMAlloc(sizeof(WsStruct));
tempa->entries=0;
tempa->substructs=0;
InsQue(tempa,p);
k=0;
for (j=i;j<p->substructs;j++) {
MemCpy(&tempa->subs[k],&p->subs[j],sizeof(WsSubstruct));
tempa->entries+=tempa->subs[k++].repeats;
tempa->substructs++;
}
p->entries-=tempa->entries;
p->substructs-=tempa->substructs;
} else {
for (j=tempa->substructs-1;j>=0;j--)
MemCpy(&tempa->subs[j+1],&tempa->subs[j],sizeof(WsSubstruct));
MemCpy(&tempa->subs[0],
&p->subs[WS_SUBSTRUCTS_PER_STRUCT-1],
sizeof(WsSubstruct));
p->entries-=tempa->subs[0].repeats;
p->substructs--;
tempa->entries+=tempa->subs[0].repeats;
tempa->substructs++;
for (j=WS_SUBSTRUCTS_PER_STRUCT-2;j>=i;j--)
MemCpy(&p->subs[j+1],
&p->subs[j],sizeof(WsSubstruct));
}
} else {
for (j=p->substructs-1;j>=i;j--)
MemCpy(&p->subs[j+1],
&p->subs[j],sizeof(WsSubstruct));
}
p->entries+=s->repeats;
p->substructs++;
MemCpy(&p->subs[i],s,sizeof(WsSubstruct));
return &p->subs[i];
}
WsSubstruct *WsCondense(WsSubstruct *s,WsStruct **parent)
{
WsSubstruct *temps,*temps_l,*temps_n;
WsStruct *tempa_l,*tempa_n;
if ((*parent)->substructs==-1)
return NULL;
temps=s;
tempa_l=*parent;
temps_l=WsLast(temps,&tempa_l);
if (temps_l && temps_l->hits==temps->hits) {
temps_l->repeats+=temps->repeats;
tempa_l->entries+=temps->repeats;
WsRemove(temps,*parent);
*parent=tempa_l;
temps=temps_l;
}
tempa_n=*parent;
temps_n=WsNext(temps,&tempa_n);
if (temps_n && temps_n->hits==temps->hits) {
temps->repeats=temps->repeats+temps_n->repeats;
(*parent)->entries=(*parent)->entries+temps_n->repeats;
WsRemove(temps_n,tempa_n);
}
return temps;
}
I8 WsIncHits(WsMatrix *m,I8 col,I8 row)
{
I8 row_base,substruct,repeats;
WsSubstruct sn,*temps,*temps1,*temps_l;
WsStruct *tempa,*tempa1,*tempa_l;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return 0;
tempa=WsFindStruct(m,col,row,&row_base,&substruct);
temps=&tempa->subs[substruct];
repeats=temps->repeats;
if (repeats==1) {
temps->hits++;
temps=WsCondense(temps,&tempa);
} else {
if (row==row_base) {
temps->repeats--;
tempa->entries--;
sn.hits=1;
sn.repeats=1;
tempa_l=tempa;
if (!(temps_l=WsLast(&tempa->subs[substruct],&tempa_l))) {
tempa_l=tempa->last; //header
temps_l=&tempa_l->subs[WS_SUBSTRUCTS_PER_STRUCT-1];
}
temps=WsInsert(&sn,&tempa_l,temps_l);
temps=WsCondense(temps,&tempa_l);
} else if (row==repeats-1+row_base) {
temps->repeats--;
tempa->entries--;
sn.hits=1;
sn.repeats=1;
temps=WsInsert(&sn,&tempa,temps);
temps=WsCondense(temps,&tempa);
} else {
tempa->entries-=repeats;
sn.hits=temps->hits+1;
sn.repeats=1;
tempa1=tempa;
temps1=temps;
temps=WsInsert(&sn,&tempa1,temps1);
temps1->repeats=row-row_base;
tempa->entries+=temps1->repeats;
sn.repeats=row_base+repeats-(row+1);
sn.hits=temps1->hits;
WsInsert(&sn,&tempa1,temps);
}
}
m->n++;
m->side[col].col_hits++;
m->side[row].row_hits++;
return temps->hits;
}
void WsAddSingleFile(LTDirEntry *tempd,BoolU4 compile)
{
I1 ch,ch1,*buf,*ptr,*ptr2;
WsHashEntry *cur_ptr,*last_ptr=NULL;
I8 k=0;
buf=ReadTextFile(tempd->full_name);
ptr=buf;
while (ch=*ptr++) {
while (ch && !Bt(alpha_numeric_bitmap,ch))
ch=*ptr++;
if (!ch) break;
ptr--;
ptr2=ptr;
do ch=*ptr2++;
while (Bt(alpha_numeric_bitmap,ch));
ptr2--;
ch1=*ptr2;
*ptr2=0;
if (*ptr) {
if (!compile)
WsAddHash(ptr);
else {
cur_ptr=FindHashEntry(ptr,ws_hash_table,HTT_WORD);
if (cur_ptr->num<0)
cur_ptr=NULL;
else
if (last_ptr)
WsIncHits(ws_matrix,last_ptr->num,cur_ptr->num);
last_ptr=cur_ptr;
}
ptr=ptr2+1;
}
if (!ch1) break;
*ptr2=ch1;
}
Free(buf);
}
void WsAddGlossFile(LTDirEntry *tempd)
{
LtfEntry *ll;
WsHashEntry *temph;
Ltf *l=LtfRead(tempd->full_name);
I1 *temp;
ll=l->dummy.next;
while (ll!=l) {
if (ll->btype==LTFT_ANCHOR) {
if (temph=FindHashEntry(ll->aux_str,
ws_hash_table,HTT_WORD)) {
temp=MSPrintF("FA:%s,%s",
tempd->full_name,ll->aux_str);
AFree(temph->glossary);
temph->glossary=ANewStr(temp);
Free(temp);
}
}
ll=ll->next;
}
LtfDel(l);
}
I8 WsSort(WsHashEntry **e1,WsHashEntry **e2)
{
I8 r;
if (!(r=(*e2)->hits - (*e1)->hits))
r=StrCmp((*e1)->word,(*e2)->word);
return r;
}
I8 WsSkipCrap(I1 *src,I8 len)
{
I8 j;
j=len-1;
while (j>=0) {
if (Bt(alpha_numeric_bitmap,src[j]))
break;
else
j--;
}
return j+1;
}
I8 WsPriorWordInStr(I1 *src,I1 *dst,I8 len,I8 buf_size)
{
I8 i,j=0,k;
BoolU4 cont=TRUE;
i=len-1;
while (i>=0 && cont) {
if (!Bt(alpha_numeric_bitmap,src[i]))
cont=FALSE;
else
i--;
}
if (i>=-1 && len>0)
for (k=i+1;k<len && j<buf_size-1;k++)
dst[j++]=src[k];
dst[j]=0;
return i+1;
}
BoolU8 WsPartialMatch(I1 *partial,I1 *complete)
{
I8 i,l=StrLen(partial);
for (i=0;i<l;i++)
if (partial[i]!=complete[i])
return FALSE;
return TRUE;
}
void WsFillin(I8 n)
{
I1 *s;
I8 len;
n--;
if (n>=0 && n<ws_num_fillins) {
s=ws_sorted_words[ws_fillin_matches[n]]->word;
len=StrLen(s);
if (len>ws_partial_len)
Auto(s+ws_partial_len);
}
}
void WsMan(I8 n,TssStruct *parent=NULL)
{
I1 *buf;
WsHashEntry *tempw;
SysHashEntry *temph;
BoolU4 old_preempt=Preempt(OFF);
n--;
if (n>=0 && n<ws_num_fillins) {
if (tempw=ws_sorted_words[ws_fillin_matches[n]]) {
buf=tempw->glossary;
if (temph=FindHashEntry(tempw->word,Fs->hash_table,HTT_ALL)) {
if (temph->source_link)
buf=temph->source_link;
}
if (buf) {
buf=MSPrintF("Edit(\"%s\");",buf);
Preempt(old_preempt);
PopUp(buf,parent);
Free(buf);
}
}
}
Preempt(old_preempt);
}
void WsAddFillin(I8 i,I8 j,I8 old_num_fillins)
{
BoolU4 cont;
I8 k;
if (ws_num_fillins<WS_MAX_FILLINS || i>ws_fillin_scores[ws_num_fillins-1] ||
i==ws_fillin_scores[ws_num_fillins-1] && ws_sorted_words[j]->hits>ws_fillin_hits[ws_num_fillins-1]) {
cont=TRUE;
for (k=ws_num_fillins-1;k>=old_num_fillins && cont;k--)
if (i<=ws_fillin_scores[k] || i==ws_fillin_scores[k] && ws_sorted_words[j]->hits<=ws_fillin_hits[k]) {
cont=FALSE;
k++; //offset k--
} else {
ws_fillin_scores[k+1]=ws_fillin_scores[k];
ws_fillin_matches[k+1]=ws_fillin_matches[k];
ws_fillin_hits[k+1]=ws_fillin_hits[k];
}
if (ws_num_fillins<WS_MAX_FILLINS)
ws_num_fillins++;
ws_fillin_scores[k+1]=i;
ws_fillin_hits[k+1]=ws_sorted_words[j]->hits;
ws_fillin_matches[k+1]=j;
}
}
void WsPutChoices(Ltf *l,Ltf *aux,Ltf *focus_l,LtfEntry *ll,TssStruct *focus_tss)
{
I8 i,j,k,data_col;
I1 ch=0,*buf,*buf1,*src=NULL,*st;
WsHashEntry *w2;
U8 timeout_jiffies=Jiffies+JIFFY_FREQ*20/1000;
SysHashEntry *temph;
src=LtfGetLine(focus_l,ll,&data_col);
i=StrLen(src);
buf=MAlloc(i+1);
buf1=MAlloc(i+1);
if (data_col==-1)
data_col=StrLen(i);
data_col=WsPriorWordInStr(src,buf,data_col,256);
ws_partial_len=StrLen(buf);
data_col=WsSkipCrap(src,data_col);
data_col=WsPriorWordInStr(src,buf1,data_col,256);
if (ws_cur_word) {
if (!StrCmp(ws_cur_word,buf))
goto done;
}
st=ws_cur_word;
ws_cur_word=ANewStr(buf);
AFree(st);
Preempt(ON);
if (StrLen(buf1))
w2=FindHashEntry(buf1,ws_hash_table,HTT_WORD);
else
w2=NULL;
ws_num_fillins=0;
if (w2 && w2->num<ws_num_matrix_words)
for (j=0;j<ws_num_matrix_words && Jiffies<timeout_jiffies;j++)
if (WsPartialMatch(ws_cur_word,ws_sorted_words[j]->word)) {
i=WsGetHits(ws_matrix,w2->num,ws_sorted_words[j]->num);
WsAddFillin(i,j,0);
}
k=ws_num_fillins;
for (j=0;j<ws_num_words && Jiffies<timeout_jiffies;j++)
if (WsPartialMatch(ws_cur_word,ws_sorted_words[j]->word))
WsAddFillin(0,j,k);
Preempt(OFF);
done:
LtfReset(l,TRUE);
l->flags|=LTFF_MIN_SIZE;
l->start_text_attribute=(LTBLUE<<4)+BLACK;
aux->start_text_attribute=(LTBLUE<<4)+BLACK;
Fs->text_attribute=l->start_text_attribute;
Fs->border_attribute=l->start_text_attribute;
LtfPrintF(l,"Word:%-20ts\r\n",ws_cur_word);
for (i=0;i<ws_num_fillins;i++) {
st=ws_sorted_words[ws_fillin_matches[i]]->word;
if (ws_sorted_words[ws_fillin_matches[i]]->glossary)
ch='#';
else
ch=CH_SPACE;
if (focus_tss) {
temph=FindHashEntry(st,focus_tss->hash_table,HTT_ALL);
if (temph) {
if (temph->source_link)
ch='*';
}
}
LtfPrintF(l,"%cF%02d %-20ts\r\n",ch,i+1,st);
}
WsdAddDictWords(l);
LtfRecalc(l);
Bts(&Fs->crt_flags,CRTf_SHOW);
WinToTop(Fs);
Free(src);
Free(buf);
Free(buf1);
}
void WsTsk()
{
TssStruct *focus_tss;
Ltf *l;
LtfEntry *ll;
InitLocalTask;
UseConsoleLtf(NULL);
Fs->win_left=50;
do {
Sleep(333);
if (Bt(&ws_flags,WSf_ENABLE)) {
focus_tss=sys_cur_focus_task;
while (Bt(&focus_tss->task_flags,TSSf_INPUT_FILTER_TASK))
focus_tss=focus_tss->parent_tss;
if (ValidateTss(focus_tss)) {
l=focus_tss->cur_ltf;
if (l && focus_tss!=Fs) {
ll=l->cur_entry;
if (ll) {
if (ll==l) ll=ll->last;
while (ll->last!=l && (ll->btype==LTFT_CR ||
ll->btype==LTFT_SOFT_CR))
ll=ll->last;
while ((ll->last->btype)!=LTFT_CR && ll->last!=l)
ll=ll->last;
if (Bt(&ws_flags,WSf_ENABLE))
WsPutChoices(Fs->cur_ltf,Fs->aux_ltf,l,ll,focus_tss);
}
}
}
}
} while (!ScanKey);
ws_task=NULL;
}
void WsTraverseMainFilelist(WsFilemaskEntry *tempfm,BoolU4 compile)
{
WsFilemaskEntry *tempfm1;
LTDirEntry *tempm;
I8 i;
while (tempfm) {
tempfm1=tempfm->next;
if (!compile) {
tempm=FindFiles(tempfm->mask,1<<FUf_RECURSE);
tempfm->flist=OrderFiles(tempm,&tempfm->cnt);
}
for (i=0;i<tempfm->cnt;i++) {
tempm=tempfm->flist[i];
if (IsTextFile(tempm->name)) {
coutln tempm->full_name;
WsAddSingleFile(tempm,compile);
}
if (compile)
DelLTDirEntry(tempm);
}
if (compile) {
Free(tempfm->flist);
Free(tempfm);
}
tempfm=tempfm1;
}
}
void WsTraverseGlossFilelist(WsFilemaskEntry *tempfm)
{
WsFilemaskEntry *tempfm1;
LTDirEntry *tempm;
I8 i;
while (tempfm) {
tempfm1=tempfm->next;
tempm=FindFiles(tempfm->mask,1<<FUf_RECURSE);
tempfm->flist=OrderFiles(tempm,&tempfm->cnt);
for (i=0;i<tempfm->cnt;i++) {
tempm=tempfm->flist[i];
if (WildCardMatch("*.GL?",tempm->name)) {
coutln tempm->full_name;
WsAddGlossFile(tempm);
}
DelLTDirEntry(tempm);
}
Free(tempfm->flist);
Free(tempfm);
tempfm=tempfm1;
}
}
void WsDelMatrix(WsMatrix *m)
{
I8 i;
WsStruct *tempw,*tempw1,*tempw2;
if (!m) return;
for (i=0;i<WS_MAX_MATRIX_WORDS;i++) {
tempw1=&m->side[i];
tempw=tempw1->next;
while (tempw!=tempw1) {
tempw2=tempw->next;
AFree(tempw);
tempw=tempw2;
}
}
AFree(m);
}
public BoolU8 WordStat(BoolU8 val=ON)
{
BoolU4 old_wordstat=FALSE,
old_preempt=Preempt(OFF);
if (val) {
Bts(&ws_flags,WSf_ENABLE);
if (ValidateTss(ws_task))
old_wordstat=TRUE;
else
ws_task=Spawn(&WsTsk,"WordStat");
} else {
Btr(&ws_flags,WSf_ENABLE);
if (ValidateTss(ws_task)) {
old_wordstat=TRUE;
Kill(ws_task);
while (ValidateTss(ws_task))
SwapInNext;
ws_task=NULL;
}
Bts(&ws_flags,WSf_ENABLE);
}
Preempt(old_preempt);
return old_wordstat;
}
public void WsInit(I1 *mask)
// Separate directories with ';'
{
I1 *buf,buf2[512];
I8 i,j=0;
WsHashEntry *tempw;
BoolU4 old_wordstat;
WsFilemaskEntry *tempfm,*tempfm1;
while (Bts(&ws_flags,WSf_INIT_IN_PROGRESS))
SwapInNext;
old_wordstat=WordStat(OFF);
if (Fs==adam_tss)
DelHashTable(ws_hash_table);
else
Adam("DelHashTable(ws_hash_table);");
ws_hash_table=NewHashTable(0x4000,adam_tss);
ws_num_words=0;
ws_num_matrix_words=0;
AFree(ws_cur_word);
ws_cur_word=NULL;
tempfm1=NULL;
buf=NewStr(mask);
do {
RemoveFirstSeg(buf,";",buf2);
if (*buf2) {
tempfm=MAlloc(sizeof(WsFilemaskEntry));
tempfm->next=tempfm1;
tempfm1=tempfm;
tempfm->mask=NewStr(buf2);
tempfm->flist=NULL;
}
} while (*buf2);
Free(buf);
coutln "\r\n\r\nPass #1";
WsTraverseMainFilelist(tempfm1,FALSE);
AFree(ws_sorted_words);
ws_sorted_words=AMAlloc(sizeof(void *)*ws_num_words);
for (i=0;i<=ws_hash_table->mask;i++) {
tempw=ws_hash_table->body[i];
while (tempw) {
ws_sorted_words[j++]=tempw;
tempw=tempw->next;
}
}
QSort(ws_sorted_words,ws_num_words,sizeof(void *),&WsSort);
for (i=0;i<ws_num_words;i++)
ws_sorted_words[i]->num=i;
if (ws_num_words<=WS_MAX_MATRIX_WORDS)
ws_num_matrix_words=ws_num_words;
else
ws_num_matrix_words=WS_MAX_MATRIX_WORDS;
WsDelMatrix(ws_matrix);
ws_matrix=AMAlloc(sizeof(WsMatrix));
WsInitSides(ws_matrix);
coutln "\r\n\r\nPass #2";
WsTraverseMainFilelist(tempfm1,TRUE);
tempfm1=NULL;
buf=NewStr(mask);
do {
RemoveFirstSeg(buf,";",buf2);
if (*buf2) {
tempfm=MAlloc(sizeof(WsFilemaskEntry));
tempfm->next=tempfm1;
tempfm1=tempfm;
tempfm->mask=NewStr(buf2);
tempfm->flist=NULL;
}
} while (*buf2);
Free(buf);
coutln "\r\n\r\nGlossary Pass";
WsTraverseGlossFilelist(tempfm1);
AFree(ws_dict_word_list);
WsdLoadWords;
WordStat(old_wordstat);
Btr(&ws_flags,WSf_INIT_IN_PROGRESS);
}