/* Q -- A simple parser for Quark Express 4.1 files
Copyright (C) 2001 Frans Faase
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., 675 Mass Ave, Cambridge, MA 02139, USA.
GNU General Public License:
http://home.wxs.nl/~faase009/GNU.txt
*/
#include <stdio.h>
#define DUMP_BLOCK(X) /*printf X*/
#define DUMP_TRAIL(X) /*printf X*/
#define DUMP_FORMAT(X) /*printf X*/
typedef int bool;
#define TRUE 1
#define FALSE 0
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long lword;
byte *buf;
lword flen = 0L;
lword fpos = 0L;
lword glword(lword *rpos)
{
lword pos = *rpos;
lword b1 = buf[pos++],
b2 = buf[pos++],
b3 = buf[pos++],
b4 = buf[pos++];
*rpos = pos;
return b1 + (b2 << 8) + (b3 << 16) + (b4 << 24);
}
word gword(lword *rpos)
{
lword pos = *rpos;
lword b1 = buf[pos++],
b2 = buf[pos++];
*rpos = pos;
return b1 + (b2 << 8);
}
lword blockend;
void skip(lword *rpos)
{
if (*rpos == blockend)
{
long nextblock;
printf("At %0X ", *rpos);
nextblock = glword(rpos);
if (nextblock < 0)
{
word nrblocks;
*rpos = (-nextblock) * 256 - 256;
nrblocks = gword(rpos);
blockend = *rpos - 2 + 256 * nrblocks - 4;
}
else
{
*rpos = nextblock * 256 - 256;
blockend = *rpos + 256 - 4;
}
DUMP_BLOCK(("\nStart new block at %8X till %8X\n",
*rpos, blockend));
}
}
lword xlword(lword *rpos, lword lines[], int nr_lines)
{
lword w1, w2;
skip(rpos);
w1 = gword(rpos);
skip(rpos);
w2 = gword(rpos);
return (w2 << 16) | w1;
}
word xword(lword *rpos, lword lines[], int nr_lines)
{
skip(rpos);
return gword(rpos);
}
main ()
{ FILE *f = fopen("p2.qxd", "r");
word blnr = 0;
buf = (byte*)malloc(500000);
flen = fread(buf, 1, 500000, f);
fclose(f);
printf("Length = %ld bytes\n",flen);
while (fpos < 55 * 256)
{ int i;
printf("%4d %06x ", blnr, fpos);
blnr++;
for (i = 0; i < 256; i++)
{ byte ch = buf[fpos];
fpos++;
if (i < 30)
if (ch >= ' ' && ch < 126)
printf(" %c", ch);
else
printf("%02X", (word)ch);
}
printf("\n");
}
printf("--------------\n");
while (fpos < flen)
{ int i;
lword code;
lword len;
word nr;
lword line[1000];
lword linelen[1000];
lword nr_a;
word acode[1000];
lword apos[1000];
lword nr_b;
word bcode[1000];
lword bpos[1000];
lword nr_char;
int ai;
lword atill;
int bi, bit;
lword btill;
printf("\n%4d %06x ", fpos / 256, fpos);
blnr++;
blockend = fpos + 256 - 4;
code = glword(&fpos);
printf("code = %ld\n", code);
len = glword(&fpos);
nr = len / 6;
DUMP_FORMAT(("%08X %d\n", len, nr));
bit = 0;
if (nr <= 0 || nr >= 100)
{
printf("%ld", nr);
return;
}
for (i = 0; i < nr; i++)
{
line[i] = xlword(&fpos, line, i);
linelen[i] = xword(&fpos, line, i);
DUMP_FORMAT(("\n %08X %d", line[i], linelen[i]));
}
{ lword chcount = 0L;
for (i = 0; i < nr; i++)
{ int j;
lword lpos = line[i]*256 - 256;
for (j = 0; j < linelen[i]; j++)
{
chcount++;
if (buf[lpos++] == 0x0D)
{
DUMP_FORMAT(("\n paragraph of %X charaters", chcount));
bpos[bit++] = chcount;
chcount = 0L;
}
}
}
DUMP_FORMAT(("\n paragraph of %X charaters", chcount));
bpos[bit++] = chcount;
}
nr_a = xlword(&fpos, line, nr);
DUMP_FORMAT(("\n nr a = %ld", nr_a));
for (i = 0; i < nr_a / 6; i++)
{
acode[i] = xword(&fpos, line, nr);
apos[i] = xlword(&fpos, line, nr);
DUMP_FORMAT(("\n a: %08X %d", apos[i], acode[i]));
}
nr_b = xlword(&fpos, line, nr);
DUMP_FORMAT(("\n nr b = %ld", nr_b));
for (i = 0; i < nr_b / 6; i++)
{ lword expos;
bcode[i] = xword(&fpos, line, nr);
expos = xlword(&fpos, line, nr);
if (expos != bpos[i])
{
printf("!!! pos : %X, expect %X found %X\n",
fpos - 4, bpos[i], expos);
return 1;
}
DUMP_FORMAT(("\n b: %08X %d", bpos[i], bcode[i]));
}
DUMP_FORMAT(("\n"));
nr_char = 0;
ai = 0;
bi = 0;
while (fpos % 256)
{ byte b = buf[fpos++];
if (b != 0)
printf("!!! At %08X have %d\n", fpos, b);
}
printf("\n");
if (bi < nr_b / 6)
{
printf("<P%d>", bcode[bi]);
btill = nr_char + bpos[bi];
}
if (ai < nr_a / 6)
{
printf("<C%d>", acode[ai]);
atill = nr_char + apos[ai];
}
for (i = 0; i < nr; i++)
{ int j;
lword lpos = line[i]*256 - 256;
for (j = 0; j < linelen[i]; j++)
{ byte ch = buf[lpos++];
if (nr_char == atill)
{
printf("</C%d>", acode[ai]);
ai++;
if (ai < nr_a / 6)
{
printf("<C%d>", acode[ai]);
atill = nr_char + apos[ai];
}
}
if (nr_char == btill)
{
printf("</P%d>", bcode[bi]);
bi++;
if (bi < nr_b / 6)
{
printf("<P%d>", bcode[bi]);
btill = nr_char + bpos[bi];
}
}
nr_char++;
if (ch >= ' ' && ch < 126)
printf("%c", ch);
else
printf("(%02X)", (unsigned int)ch);
}
if (j < 256)
DUMP_TRAIL(("-- %d\n",j));
for (; j < 256; j++)
{ byte b = buf[lpos++];
DUMP_TRAIL(("%02X ", b));
}
DUMP_TRAIL(("\n"));
if (lpos > fpos)
fpos = lpos;
}
if (nr_char == atill)
{
printf("</C%d>", acode[ai]);
}
if (nr_char == btill)
{
printf("</P%d>", bcode[bi]);
}
if (nr_a / 6 - ai != 1 || nr_b / 6 - bi != 1)
printf("-- %d %d\n", nr_a / 6 - ai, nr_b / 6 - bi);
}
}