home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * 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 < (int)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;
- for(;;)
- {
- if ( _size >= (int)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;
-
- for(;;)
- {
- 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;
-
- for(;;)
- {
- 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 */
-