Category : C Source Code
Archive   : FRASRC18.ZIP
Filename : HELPCOM.H

 
Output of file : HELPCOM.H contained in archive : FRASRC18.ZIP

/*
* helpcom.h
*
*
* Common #defines, structures and code for HC.C and HELP.C
*
*/

#ifndef HELPCOM_H
#define HELPCOM_H

#include "port.h"

/*
* help file signature
* If you get a syntax error, remove the LU from the end of the number.
*/

#define HELP_SIG (0xAFBC1823LU)


/*
* commands imbedded in the help text
*/

#define CMD_LITERAL 1 /* next char taken literally */
#define CMD_PARA 2 /* paragraph start code */
#define CMD_LINK 3 /* hot-link start/end code */
#define CMD_FF 4 /* force a form-feed */
#define CMD_XONLINE 5 /* exclude from online help on/off */
#define CMD_XDOC 6 /* exclude from printed document on/off */
#define CMD_CENTER 7 /* center this line */
#define CMD_SPACE 8 /* next byte is count of spaces */

#define MAX_CMD 8


/*
* on-line help dimensions
*/

#define SCREEN_WIDTH (78)
#define SCREEN_DEPTH (22)
#define SCREEN_INDENT (1)


/*
* printed document dimensions
*/

#define PAGE_WIDTH (72) /* width of printed text */
#define PAGE_INDENT (2) /* indent all text by this much */
#define TITLE_INDENT (1) /* indent titles by this much */

#define PAGE_RDEPTH (59) /* the total depth (inc. heading) */
#define PAGE_HEADING_DEPTH (3) /* depth of the heading */
#define PAGE_DEPTH (PAGE_RDEPTH-PAGE_HEADING_DEPTH) /* depth of text */


/*
* Document page-break macros. Goto to next page if this close (or closer)
* to end of page when starting a CONTENT, TOPIC, or at a BLANK line.
*/

#define CONTENT_BREAK (7) /* start of a "DocContent" entry */
#define TOPIC_BREAK (4) /* start of each topic under a DocContent entry */
#define BLANK_BREAK (2) /* a blank line */


/*
* tokens returned by find_token_length
*/

#define TOK_DONE (0) /* len == 0 */
#define TOK_SPACE (1) /* a run of spaces */
#define TOK_LINK (2) /* an entire link */
#define TOK_PARA (3) /* a CMD_PARA */
#define TOK_NL (4) /* a new-line ('\n') */
#define TOK_FF (5) /* a form-feed (CMD_FF) */
#define TOK_WORD (6) /* a word */
#define TOK_XONLINE (7) /* a CMD_XONLINE */
#define TOK_XDOC (8) /* a CMD_XDOC */
#define TOK_CENTER (9) /* a CMD_CENTER */


/*
* modes for find_token_length() and find_line_width()
*/

#define ONLINE 1
#define DOC 2


/*
* struct PD_INFO used by process_document()
*/

typedef struct
{

/* used by process_document -- look but don't touch! */

int pnum,
lnum;

/* PD_GET_TOPIC is allowed to change these */

char far *curr;
unsigned len;

/* PD_GET_CONTENT is allowed to change these */

char far *id;
char far *title;
int new_page;

/* general parameters */

char far *s;
int i;


} PD_INFO;


/*
* Commands passed to (*get_info)() and (*output)() by process_document()
*/

enum PD_COMMANDS
{

/* commands sent to pd_output */

PD_HEADING, /* call at the top of each page */
PD_FOOTING, /* called at the end of each page */
PD_PRINT, /* called to send text to the printer */
PD_PRINTN, /* called to print a char n times */
PD_PRINT_SEC, /* called to print the section title line */
PD_START_SECTION, /* called at the start of each section */
PD_START_TOPIC, /* called at the start of each topic */
PD_SET_SECTION_PAGE, /* set the current sections page number */
PD_SET_TOPIC_PAGE, /* set the current topics page number */
PD_PERIODIC, /* called just before curr is incremented to next token */

/* commands sent to pd_get_info */

PD_GET_CONTENT,
PD_GET_TOPIC,
PD_RELEASE_TOPIC,
PD_GET_LINK_PAGE

} ;


typedef int (*PD_FUNC)(int cmd, PD_INFO *pd, VOIDPTR info);


int _find_token_length(char far *curr, unsigned len, int *size, int *width);
int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width);
int find_line_width(int mode, char far *curr, unsigned len);
int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info);


/*
* Code common to both HC.C and HELP.C (in Fractint).
* #include INCLUDE_COMMON once for each program
*/


#endif
#ifdef INCLUDE_COMMON


#ifndef XFRACT
#define getint(ptr) (*(int far *)(ptr))
#define setint(ptr,n) (*(int far *)(ptr)) = n
#else
/* Get an int from an unaligned pointer
* This routine is needed because this program uses unaligned 2 byte
* pointers all over the place.
*/
getint(ptr)
char *ptr;
{
int s;
bcopy(ptr,&s,sizeof(int));
return s;
}

/* Set an int to an unaligned pointer */
void setint(ptr, n)
int n;
char *ptr;
{
bcopy(&n,ptr,sizeof(int));
}
#endif


static int is_hyphen(char far *ptr) /* true if ptr points to a real hyphen */
{ /* checkes for "--" and " -" */
if ( *ptr != '-' )
return (0); /* that was easy! */

--ptr;

return ( *ptr!=' ' && *ptr!='-' );
}


int _find_token_length(register char far *curr, unsigned len, int *size, int *width)
{
register int _size = 0;
register int _width = 0;
int tok;

if (len == 0)
tok = TOK_DONE;

else
{
switch ( *curr )
{
case ' ': /* it's a run of spaces */
tok = TOK_SPACE;
while ( *curr == ' ' && _size < len )
{
++curr;
++_size;
++_width;
}
break;

case CMD_SPACE:
tok = TOK_SPACE;
++curr;
++_size;
_width = *curr;
++curr;
++_size;
break;

case CMD_LINK:
tok = TOK_LINK;
_size += 1+3*sizeof(int); /* skip CMD_LINK + topic_num + topic_off + page_num */
curr += 1+3*sizeof(int);

while ( *curr != CMD_LINK )
{
if ( *curr == CMD_LITERAL )
{
++curr;
++_size;
}
++curr;
++_size;
++_width;
assert(_size < len);
}

++_size; /* skip ending CMD_LINK */
break;

case CMD_PARA:
tok = TOK_PARA;
_size += 3; /* skip CMD_PARA + indent + margin */
break;

case CMD_XONLINE:
tok = TOK_XONLINE;
++_size;
break;

case CMD_XDOC:
tok = TOK_XDOC;
++_size;
break;

case CMD_CENTER:
tok = TOK_CENTER;
++_size;
break;

case '\n':
tok = TOK_NL;
++_size;
break;

case CMD_FF:
tok = TOK_FF;
++_size;
break;

default: /* it must be a word */
tok = TOK_WORD;
while (1)
{
if ( _size >= len )
break;

else if ( *curr == CMD_LITERAL )
{
curr += 2;
_size += 2;
_width += 1;
}

else if ( *curr == '\0' )
{
assert(0);
}

else if ((unsigned)*curr <= MAX_CMD || *curr == ' ' ||
*curr == '\n')
break;

else if ( *curr == '-' )
{
++curr;
++_size;
++_width;
if ( is_hyphen(curr-1) )
break;
}

else
{
++curr;
++_size;
++_width;
}
}
break;
} /* switch */
}

if (size != NULL) *size = _size;
if (width != NULL) *width = _width;

return (tok);
}


int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width)
{
int tok;
int t;
int _size;

tok = _find_token_length(curr, len, &t, width);

if ( (tok == TOK_XONLINE && mode == ONLINE) ||
(tok == TOK_XDOC && mode == DOC) )
{
_size = 0;

while (1)
{
curr += t;
len -= t;
_size += t;

tok = _find_token_length(curr, len, &t, NULL);

if ( (tok == TOK_XONLINE && mode == ONLINE) ||
(tok == TOK_XDOC && mode == DOC) ||
(tok == TOK_DONE) )
break;
}

_size += t;
}
else
_size = t;

if (size != NULL )
*size = _size;

return (tok);
}


int find_line_width(int mode, char far *curr, unsigned len)
{
int size = 0,
width = 0,
lwidth = 0,
done = 0,
tok;

do
{
tok = find_token_length(mode, curr, len, &size, &width);

switch(tok)
{
case TOK_DONE:
case TOK_PARA:
case TOK_NL:
case TOK_FF:
done = 1;
break;

case TOK_XONLINE:
case TOK_XDOC:
case TOK_CENTER:
curr += size;
len -= size;
break;

default: /* TOK_SPACE, TOK_LINK or TOK_WORD */
lwidth += width;
curr += size;
len -= size;
break;
}
}
while ( !done );

return (lwidth);
}


#define DO_PRINTN(ch,n) ( pd.s = &(ch), pd.i = (n), output(PD_PRINTN, &pd, info) )
#define DO_PRINT(str,n) ( pd.s = (str), pd.i = (n), output(PD_PRINT, &pd, info) )


int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info)
{
int skip_blanks;
int tok;
int size,
width;
int col;
char page_text[10];
PD_INFO pd;
char nl = '\n',
sp = ' ';
int first_section,
first_topic;

pd.pnum = 1;
pd.lnum = 0;

col = 0;

output(PD_HEADING, &pd, info);

first_section = 1;

while ( get_info(PD_GET_CONTENT, &pd, info) )
{
if ( !output(PD_START_SECTION, &pd, info) )
return (0);

if ( pd.new_page && pd.lnum != 0 )
{
if ( !output(PD_FOOTING, &pd, info) )
return (0);
++pd.pnum;
pd.lnum = 0;
if ( !output(PD_HEADING, &pd, info) )
return (0);
}

else
{
if ( pd.lnum+2 > PAGE_DEPTH-CONTENT_BREAK )
{
if ( !output(PD_FOOTING, &pd, info) )
return (0);
++pd.pnum;
pd.lnum = 0;
if ( !output(PD_HEADING, &pd, info) )
return (0);
}
else if (pd.lnum > 0)
{
if ( !DO_PRINTN(nl, 2) )
return (0);
pd.lnum += 2;
}
}

if ( !output(PD_SET_SECTION_PAGE, &pd, info) )
return (0);

if ( !first_section )
{
if ( !output(PD_PRINT_SEC, &pd, info) )
return (0);
++pd.lnum;
}

col = 0;

first_topic = 1;

while ( get_info(PD_GET_TOPIC, &pd, info) )
{
if ( !output(PD_START_TOPIC, &pd, info) )
return (0);

skip_blanks = 0;
col = 0;

if ( !first_section ) /* do not skip blanks for DocContents */
{
while (pd.len > 0)
{
tok = find_token_length(DOC, pd.curr, pd.len, &size, NULL);
if (tok != TOK_XDOC && tok != TOK_XONLINE &&
tok != TOK_NL && tok != TOK_DONE )
break;
pd.curr += size;
pd.len -= size;
}
if ( first_topic && pd.len != 0 )
{
if ( !DO_PRINTN(nl, 1) )
return (0);
++pd.lnum;
}
}

if ( pd.lnum > PAGE_DEPTH-TOPIC_BREAK )
{
if ( !output(PD_FOOTING, &pd, info) )
return (0);
++pd.pnum;
pd.lnum = 0;
if ( !output(PD_HEADING, &pd, info) )
return (0);
}
else if ( !first_topic )
{
if ( !DO_PRINTN(nl, 1) )
return (0);
pd.lnum++;
}

if ( !output(PD_SET_TOPIC_PAGE, &pd, info) )
return (0);

do
{
if ( !output(PD_PERIODIC, &pd, info) )
return (0);

tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);

switch ( tok )
{
case TOK_PARA:
{
int indent,
margin;
unsigned holdlen = 0;
char far *holdcurr = 0;
int in_link = 0;

++pd.curr;

indent = *pd.curr++;
margin = *pd.curr++;

pd.len -= 3;

if ( !DO_PRINTN(sp, indent) )
return (0);

col = indent;

while (1)
{
if ( !output(PD_PERIODIC, &pd, info) )
return (0);

tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);

if ( tok == TOK_NL || tok == TOK_FF )
break;

if ( tok == TOK_DONE )
{
if (in_link == 0)
{
col = 0;
++pd.lnum;
if ( !DO_PRINTN(nl, 1) )
return (0);
break;
}

else if (in_link == 1)
{
tok = TOK_SPACE;
width = 1;
size = 0;
++in_link;
}

else if (in_link == 2)
{
tok = TOK_WORD;
width = strlen(page_text);
col += 8 - width;
size = 0;
pd.curr = page_text;
++in_link;
}

else if (in_link == 3)
{
pd.curr = holdcurr;
pd.len = holdlen;
in_link = 0;
continue;
}
}

if ( tok == TOK_PARA )
{
col = 0; /* fake a nl */
++pd.lnum;
if ( !DO_PRINTN(nl, 1) )
return (0);
break;
}

if (tok == TOK_XONLINE || tok == TOK_XDOC )
{
pd.curr += size;
pd.len -= size;
continue;
}

if ( tok == TOK_LINK )
{
pd.s = pd.curr+1;
if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
{
in_link = 1;
sprintf(page_text, "(p. %d)", pd.i);
}
else
in_link = 3;
holdcurr = pd.curr + size;
holdlen = pd.len - size;
pd.len = size - 2 - 3*sizeof(int);
pd.curr += 1 + 3*sizeof(int);
continue;
}

/* now tok is TOK_SPACE or TOK_WORD */

if (col+width > PAGE_WIDTH)
{ /* go to next line... */
if ( !DO_PRINTN(nl, 1) )
return (0);
if ( ++pd.lnum >= PAGE_DEPTH )
{
if ( !output(PD_FOOTING, &pd, info) )
return (0);
++pd.pnum;
pd.lnum = 0;
if ( !output(PD_HEADING, &pd, info) )
return (0);
}

if ( tok == TOK_SPACE )
width = 0; /* skip spaces at start of a line */

if ( !DO_PRINTN(sp, margin) )
return (0);
col = margin;
}

if (width > 0)
{
if (tok == TOK_SPACE)
{
if ( !DO_PRINTN(sp, width) )
return (0);
}
else
{
if ( !DO_PRINT(pd.curr, (size==0) ? width : size) )
return (0);
}
}

col += width;
pd.curr += size;
pd.len -= size;
}

skip_blanks = 0;
width = size = 0;
break;
}

case TOK_NL:
if (skip_blanks && col == 0)
break;

++pd.lnum;

if ( pd.lnum >= PAGE_DEPTH || (col == 0 && pd.lnum >= PAGE_DEPTH-BLANK_BREAK) )
{
if ( col != 0 ) /* if last wasn't a blank line... */
{
if ( !DO_PRINTN(nl, 1) )
return (0);
}
if ( !output(PD_FOOTING, &pd, info) )
return (0);
++pd.pnum;
pd.lnum = 0;
skip_blanks = 1;
if ( !output(PD_HEADING, &pd, info) )
return (0);
}
else
{
if ( !DO_PRINTN(nl, 1) )
return (0);
}

col = 0;
break;

case TOK_FF:
if (skip_blanks)
break;
if ( !output(PD_FOOTING, &pd, info) )
return (0);
col = 0;
pd.lnum = 0;
++pd.pnum;
if ( !output(PD_HEADING, &pd, info) )
return (0);
break;

case TOK_CENTER:
width = (PAGE_WIDTH - find_line_width(DOC,pd.curr,pd.len)) / 2;
if ( !DO_PRINTN(sp, width) )
return (0);
break;

case TOK_LINK:
skip_blanks = 0;
if ( !DO_PRINT(pd.curr+1+3*sizeof(int),
size-3*sizeof(int)-2) )
return (0);
pd.s = pd.curr+1;
if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
{
width += 9;
sprintf(page_text, " (p. %d)", pd.i);
if ( !DO_PRINT(page_text, strlen(page_text)) )
return (0);
}
break;

case TOK_WORD:
skip_blanks = 0;
if ( !DO_PRINT(pd.curr, size) )
return (0);
break;

case TOK_SPACE:
skip_blanks = 0;
if ( !DO_PRINTN(sp, width) )
return (0);
break;

case TOK_DONE:
case TOK_XONLINE: /* skip */
case TOK_XDOC: /* ignore */
break;

} /* switch */

pd.curr += size;
pd.len -= size;
col += width;
}
while (pd.len > 0);

get_info(PD_RELEASE_TOPIC, &pd, info);

first_topic = 0;
} /* while */

first_section = 0;
} /* while */

if ( !output(PD_FOOTING, &pd, info) )
return (0);

return (1);
}

#undef DO_PRINT
#undef DO_PRINTN


#undef INCLUDE_COMMON
#endif /* #ifdef INCLUDE_COMMON */


  3 Responses to “Category : C Source Code
Archive   : FRASRC18.ZIP
Filename : HELPCOM.H

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/