Minix1.1/usr/src/commands/libpack.c
/* libpack - pack ASCII assembly code Author: Andy Tanenbaum */
#define BUFSIZ 20000
#define FS 1
#define WRITE 4
#define NILP (char *)0
char *table[] = {
"push ax",
"ret",
"mov bp,sp",
"push bp",
"pop bp",
"mov sp,bp",
".text",
"xor ax,ax",
"push 4(bp)",
"pop bx",
"pop si",
"cbw",
"movb al,(bx)",
"pop ax",
"xorb ah,ah",
"mov ax,#1",
"call _callm1",
"add sp,#16",
"mov bx,4(bp)",
"push 6(bp)",
"mov -2(bp),ax",
"I0013:",
"call .cuu",
"mov ax,-2(bp)",
"add 4(bp),#1",
"or ax,ax",
"jmp I0011",
"mov bx,8(bp)",
"push dx",
"mov cx,#2",
"mov bx,#2",
"I0011:",
"I0012:",
"push -2(bp)",
"mov ax,4(bp)",
"mov ax,-4(bp)",
"add sp,#6",
"and ax,#255",
"push bx",
"mov bx,-2(bp)",
"loop 2b",
"jcxz 1f",
".word 4112",
"mov ax,(bx)",
"mov -4(bp),ax",
"jmp I0013",
".data",
"mov bx,6(bp)",
"mov (bx),ax",
"je I0012",
".word 8224",
".bss",
"mov ax,#2",
"call _len",
"call _callx",
".word 28494",
".word 0",
"push -4(bp)",
"movb (bx),al",
"mov bx,ax",
"mov -2(bp),#0",
"I0016:",
".word 514",
".word 257",
"mov ",
"push ",
".word ",
"pop ",
"add ",
"4(bp)",
"-2(bp)",
"(bx)",
".define ",
".globl ",
"movb ",
"xor ",
"jmp ",
"cmp ",
"6(bp)",
"-4(bp)",
"-6(bp)",
"#16",
"_callm1",
"call ",
"8(bp)",
"xorb ",
"and ",
"sub ",
"-8(bp)",
"jne ",
".cuu",
"lea ",
"inc ",
"_M+10",
"#255",
"loop",
"jcxz",
"ax,#",
"bx,#",
"cx,#",
"ax,",
"bx,",
"cx,",
"dx,",
"si,",
"di,",
"bp,",
"ax",
"bx",
"cx",
"dx",
"si",
"di",
"bp",
"sp",
"dec ",
"neg ",
"_execve",
",#0",
0};
int bol = 1;
int white = 0;
#define MAX 128
/* This table is used to look up strings. */
struct node {
char *string;
struct node *next;
} node[MAX];
struct node *hash[MAX]; /* hash table */
char input[BUFSIZ+2];
char xbuf[BUFSIZ+2];
main()
{
int n, count, outbytes;
char *p;
hainit();
while (1) {
for (p = &input[0]; p < &input[BUFSIZ+1]; p++) *p = 0;
n = read(0, input, BUFSIZ);
if (n == BUFSIZ) {
std_err("Input file too long\n");
exit(1);
}
if (n <= 0) exit(0);
outbytes = pack88(input, xbuf, n);
write(1, xbuf, outbytes);
}
}
int pack88(inp, outp, count)
register char *inp;
char *outp;
int count;
{
/* Take a string and pack it to compact assembly code. */
int k, hit, whchar, n;
char *orig = outp;
char *inbeg = inp;
int ct;
char *p, **ppt;
struct node *nood;
/* Convert all tabs to spaces. */
p = inp;
while (p - inbeg < count) {
if (*p == '\t') *p = ' ';
p++;
}
/* Loop on every char in the buffer. */
while (1) {
/* Is the current string in the table? */
if (inp - inbeg > count) write(2, "Bug in packing algorithm\n", 25);
if (inp - inbeg == count) return(outp - orig);
/* Delete leading white space */
whchar = (*inp == ' ' ? 1 : 0);
if (bol && whchar) {
inp++;
continue;
} else {
bol = 0;
}
if (*inp == '\n') bol = 1;
/* Delete comments */
if (*inp == '|') {
while (*inp++ != '\n') ;
inp--;
bol = 1;
}
/* Compact white space */
if (white && whchar) {
inp++;
continue;
}
white = whchar;
ppt = table;
hit = 0;
/* Compute hash value for inp. */
n = (*inp + *(inp+1)) & 0177;
nood = hash[n];
while (nood != 0) {
if (match(inp, nood->string)) {
*outp++ = (char) (128 + (nood - node));
inp += strlen(nood->string);
hit++;
break;
}
nood = nood->next;
}
if (hit == 0) *outp++ = *inp++;
}
}
int match(s1, s2)
register char *s1, *s2;
{
while (*s2 != 0) {
if (*s1++ != *s2++) return(0);
}
return(1);
}
hainit()
{
/* Initialize the hash tables. */
int n, i, free;
char *p;
struct node *nood;
free = 0; /* next free slot in node table */
for (i = 0; i < MAX; i++) {
p = table[i];
if (p == (char *) 0) return;
n = *p + *(p+1);
n = n & 0177;
/* Enter string i on hash slot n. */
if (hash[n] == (struct node *) 0) {
hash[n] = &node[free];
} else {
/* Find the end of the chain. */
nood = hash[n];
while (nood->next != (struct node *) 0) nood = nood->next;
nood->next = &node[free];
}
node[free].string = p;
node[free].next = (struct node *) 0;
free++;
}
}