Category : Recently Uploaded Files
Archive   : DOSUIT07.ZIP
Filename : MAKEHELP.CPP

 
Output of file : MAKEHELP.CPP contained in archive : DOSUIT07.ZIP

static char RCSid[] = "$RCSfile: makehelp.cpp $ $Revision: 1.3 $";
#include
#include
#include
#include
#include "makehelp.hpp"
#include

const int maxLines = 23, maxCols = 78, maxXref = 100;
char helppage[maxLines+1][maxCols+1];
HelpXref xrefs[maxXref+1];

FILE *source;

void crash(const char *e,const char *file,unsigned line)
{
fprintf(stderr,"Assertion failure: '%s' on line %u in file '%s'\n",
e,line,file);
_exit(1);
}

main(int argc, char **argv)
{
if(argc != 2)
{
puts("makehelp - User Interface Toolkit help compiler $Revision: 1.3 $");
puts("Usage :-");
puts("makehelp ");
puts("compiles .SRC to .HLP");
exit(4);
}
source = fopen(form("%s.SRC",argv[1]),"r");
if(!source)
{
printf("Source file %s.SRC not found\n",argv[1]);
exit(3);
}

Help help(argv[1]);

if(!help.pass1())
exit(1);
if(!help.pass2())
exit(2);
return 0;
}

Help::Help(const char *helpfile)
: pages(0)
{
file = fopen(form("%s.HLP",helpfile),"wb");
if(!file)
{
printf("Cannot create help file %s.HLP\n",helpfile);
exit(3);
}
}

Help::~Help()
{
if(file)
fclose(file);
if(pages)
delete pages;

HelpKey *k;

while((k = keys.getlast()) != 0)
delete k;
}

int Help::lookup(const char *key)
{
GIterator(HelpKey) next(keys);
HelpKey *ky;

while((ky = next()) != 0)
if(*ky == key)
return ky->page();
return -1;
}

const int maxLen = 256;
static char inbuf[maxLen+2];
int lineno, pageno;

inline int printerror(const char *s)
{
printf("%s\nLine %4d:Page %2d:%s\n",inbuf,lineno,pageno+1,s);
return 0;
}

int getaline()
{
if(!fgets(inbuf,maxLen,source))
return 0;

char *e = strchr(inbuf,'\n');

if(e)
*e = 0;
lineno++;
return 1;
}

int Help::pass1()
{
int y = 0, retval = 1, xref;
char *p;

pageno = lineno = xref = 0;
while(getaline())
{
switch(inbuf[0])
{
case ';': // Comment if at start of page
if(y)
break;
continue;
case '$': // Key definition if at start of page
if(y)
break;
for(p = inbuf + 1; isspace(*p); p++)
;
if(lookup(p) >= 0)
retval = printerror("Error - Key already exists");
else
keys.add(new HelpKey(p,pageno));
continue;
case '#': // Start of new page
if(inbuf[1])
printerror("Warning - extra characters in page delimiter ignored");
xref = y = 0;
pageno++;
continue;
}

char *p = strchr(inbuf,'{');

while(p)
{
char *q = strchr(p,'}');

if(!q)
{
printerror("Warning - unterminated cross reference");
break;
}
if(xref++ == maxXref)
retval = printerror("Error - too many cross references");
p = strchr(q,'{');
}
if(y++ == maxLines)
retval = printerror("Error - page too long");
if(strlen(inbuf) > maxCols)
retval = printerror("Error - line too long");
}
if(y)
pageno++;
return retval;
}

int Help::pass2()
{
int y = 0, retval = 1, l, xref, maxw;
char *p;

pages = new long[pageno];
for(l = 0; l < pageno; l++)
pages[l] = 0;
writeheader(1);
pageno = lineno = xref = maxw = 0;
rewind(source);
while(getaline())
{
switch(inbuf[0])
{
case ';': // Comment if at start of page
if(y)
break;
continue;
case '$': // Key definition if at start of page
if(y)
break;
continue;
case '#': // Start of new page
writepage(maxw,y,xref);
xref = maxw = y = 0;
continue;
}

char *p = strchr(inbuf,'{');

while(p)
{
char *q = strchr(p+1,'}');

if(!q)
break;
*q = 0;
for(*p++ = ' '; isspace(*p); p++)
;
if((l = lookup(p)) < 0)
retval = printerror("Error - Key does not exist");
else
{
xrefs[xref].len = q - p;
xrefs[xref].x = p - inbuf;
xrefs[xref].y = y;
xrefs[xref++].pageno = l;
}
*q++ = ' ';
p = strchr(q,'{');
}
strcpy(helppage[y++],inbuf);
l = strlen(inbuf);
if(l > maxw)
maxw = l;
}
if(y)
writepage(maxw,y,xref);
writeheader(0);
return retval;
}

void Help::writeheader(int dokeys)
{
rewind(file);
fprintf(file,"%d %d\n",pageno,keys.size());
// write out page offsets
for(int i = 0; i < pageno; i++)
fprintf(file,"%6ld\n",pages[i]);
if(!dokeys)
return;

// write out key table
GIterator(HelpKey) next(keys);
HelpKey *k;

while((k = next()) != 0)
fprintf(file,"%d %s\n",k->page(),k->key());
}

void Help::writepage(int x,int y,int xref)
{
pages[pageno++] = ftell(file);
fprintf(file,"%d %d %d\n",x,y,xref);
for(int i = 0; i < y; i++)
fprintf(file,"%s\n",helppage[i]);
for(i = 0; i < xref; i++)
fprintf(file,"%d %d %d %d\n",xrefs[i].len,xrefs[i].x,xrefs[i].y,
xrefs[i].pageno);
}

HelpKey::HelpKey(const char *key,int pageno)
: k(new char[strlen(key)+1]), p(pageno)
{
if(k)
strcpy(k,key);
}

HelpKey::~HelpKey()
{
delete k;
}