📄 dict.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <string.h>
#include "cmdline.h"
#include "umem.h"
#include "module.h"
#include "dict.h"
extern HASHREC **publichash;
extern MODULE *modules;
long dictofs, dictpages, pagesize = 16;
BYTE *dictionary;
int primes[] =
{
1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139,
149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
227, 229, 233, 239, 241, 251
};
#define PRIMESIZE sizeof(primes)/sizeof(int)
static void LibHash(const char *name, int blocks, HASH *h)
{
int len = strlen(name);
const char *pb = name, *pe = name + len;
const ushort blank = ' ';
hv block_x = len | blank, bucket_d = len | blank;
hv block_d = 0, bucket_x = 0;
while (1)
{
ushort cback = *(--pe) | blank;
ushort cfront = *(pb++) | blank;
bucket_x = ROTR(bucket_x, 2) ^ cback;
block_d = ROTL(block_d, 2) ^ cback;
if (--len == 0)
break;
block_x = ROTL(block_x, 2) ^ cfront;
bucket_d = ROTR(bucket_d, 2) ^ cfront;
}
h->block_x = block_x % blocks;
h->block_d = block_d % blocks;
h->block_d = MAX(h->block_d, 1);
h->bucket_x = bucket_x % LIB_BUCKETS;
h->bucket_d = bucket_d % LIB_BUCKETS;
h->bucket_d = MAX(h->bucket_d, 1);
}
//-------------------------------------------------------------------------
void CalculateDictionary(void)
{
int i, count = 0, size = 0;
MODULE *m = modules;
long pos = pagesize, dictpages2, dictpages1;
for (i = 0; i < HASH_TABLE_SIZE; i++)
{
PUBLIC *p = publichash[i];
while (p)
{
int xx;
count++;
xx = strlen(p->name) + 1;
if (xx &1)
xx++;
size += xx;
p = p->link;
}
}
dictpages1 = (count + LIB_BUCKETS) / LIB_BUCKETS;
dictpages2 = (size + (512-38)) / (512-38) + 1;
dictpages = dictpages1 > dictpages2 ? dictpages1 : dictpages2;
restart: if (dictpages > primes[PRIMESIZE - 1])
fatal("Library dictionary too large");
for (i = 0; i < PRIMESIZE; i++)
if (primes[i] >= dictpages)
break;
dictpages = primes[i];
while (m)
{
long t;
m->offset = pos;
pos += m->len;
t = pos % pagesize;
t = t ? pagesize - t: 0;
pos += t;
m = m->link;
}
dictofs = pos + pagesize;
dictofs = (dictofs + 511) &0xfffffe00;
dictionary = AllocateMemory(dictpages *512);
for (i = 0; i < HASH_TABLE_SIZE; i++)
{
PUBLIC *p = publichash[i];
while (p)
{
HASH lhr;
BOOL put = FALSE;
int startblock;
LibHash(p->name, dictpages, &lhr);
startblock = lhr.block_x;
do
{
BYTE *dptr;
int startbucket = lhr.bucket_x;
dptr = dictionary + lhr.block_x * 512;
do
{
if (!dptr[lhr.bucket_x])
{
int start;
if (!dptr[LIB_FREEPOS])
start = 38;
else
start = dptr[LIB_FREEPOS] *2;
if (512-start >= strlen(p->name) + 3)
{
int i = strlen(p->name);
long ofs = p->mod->offset;
char *q = p->name;
dptr[lhr.bucket_x] = start / 2;
dptr[start++] = i;
while (i--)dptr[start++] = *q++;
ofs /= pagesize;
dptr[start++] = (ofs) &0xff;
dptr[start++] = (ofs >> 8) &0xff;
ofs *= pagesize;
if (start &1)
start++;
if (start == 512)
start -= 2;
dptr[LIB_FREEPOS] = start / 2;
put = TRUE;
break;
}
else
{
dptr[LIB_FREEPOS] = 0xff;
goto nextblock;
}
}
lhr.bucket_x += lhr.bucket_d;
if (lhr.bucket_x >= LIB_BUCKETS)
lhr.bucket_x -= LIB_BUCKETS;
}
while (startbucket != lhr.bucket_x)
;
if (put)
break;
nextblock: lhr.block_x += lhr.block_d;
if (lhr.block_x >= dictpages)
lhr.block_x -= dictpages;
}
while (startblock != lhr.block_x)
;
if (!put)
{
dictpages++;
goto restart;
}
p = p->link;
}
}
}
//-------------------------------------------------------------------------
void WriteDictionary(FILE *file)
{
int i;
for (i = 0; i < dictpages; i++)
{
BYTE *p = dictionary + i * 512;
fwrite(p, 1, 512, file);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -