help.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,490 行 · 第 1/3 页
C
1,490 行
switch( buffer[i+1] ) {
case H_UNDERLINE:
currentColour |= C_ULINE;
++i;
break;
case H_UNDERLINE_END:
currentColour &= ~C_ULINE;
++i;
break;
case H_BOLD:
currentColour |= C_BOLD;
++i;
break;
case H_BOLD_END:
currentColour &= ~C_BOLD;
++i;
break;
}
++i;
switch( currentColour ) {
case C_PLAIN:
currentAttr = AT( ATTR_NORMAL );
break;
case C_ULINE:
currentAttr = AT( ATTR_BRIGHT );
break;
case C_BOLD:
currentAttr = AT( ATTR_BRIGHT );
break;
case C_ULBOLD:
currentAttr = AT( ATTR_BRIGHT );
break;
}
}
}
}
static void save_line( int line, long offset )
/* Assumption: line <= lastHelpLine + 1 */
{
if( line >= maxPos ) {
maxPos = line + 10;
helpPos = HelpMemRealloc( helpPos, maxPos * sizeof( *helpPos ) );
}
if( line > lastHelpLine ) {
lastHelpLine = line;
}
if( offset == -1 ) {
helpPos[line] = -1;
} else {
helpPos[line] = offset - topPos;
}
}
static void seek_line( int line )
{
int i;
if( line > lastHelpLine ) {
HelpSeek( helpFileHdl, topPos + helpPos[lastHelpLine], HELP_SEEK_SET );
for( i = lastHelpLine; ; ++i ) {
save_line( i, HelpTell( helpFileHdl ) );
if( i == line ) break;
if( !getline() || strnicmp( helpInBuf, "::::", 4 ) == 0 ) {
maxLine = i;
break;
}
}
} else if( line >= 0 ) {
HelpSeek( helpFileHdl, topPos + helpPos[line], HELP_SEEK_SET );
}
}
static void set_slider( int pos )
{
uisetgadget( &vGadget, pos );
}
/*
* handleFooter - scan through and process footer information
*/
static void handleFooter( int *startline, SAREA *use, SAREA *line )
{
int start;
start = *startline;
if( strnicmp( helpInBuf, ":t", 2 ) == 0 ) {
++start; /* leave room for line */
for( ;; ) {
if( !getline() ) break;
if( strnicmp( helpInBuf, ":et", 3 ) == 0 ) break;
processLine( helpInBuf, helpOutBuf, start, FALSE );
putline( helpOutBuf, start );
++start;
}
vscroll_fields( &helpTab, *use, start - use->row - use->height );
vvscroll( &helpScreen, *use, start - use->row - use->height );
use->height -= start - use->row;
line->row = use->row + use->height;
uivfill( &helpScreen, *line, AT( ATTR_NORMAL ), UiGChar[UI_SBOX_HORIZ_LINE] );
topPos = HelpTell( helpFileHdl );
}
*startline = start;
}
/*
* handleHeader - scan through and process header information
*/
static void handleHeader( int *start, SAREA *line )
{
int cur;
cur = 0;
if( strnicmp( helpInBuf, ":h", 2 ) == 0 ) {
for( ;; ) {
if( !getline() ) break;
if( strnicmp( helpInBuf, ":t", 2 ) == 0 ) break;
if( strnicmp( helpInBuf, ":eh", 3 ) == 0 ) break;
processLine( helpInBuf, helpOutBuf, cur, FALSE );
putline( helpOutBuf, cur );
cur ++;
}
line->row = cur;
uivfill( &helpScreen, *line, AT( ATTR_NORMAL ), UiGChar[UI_SBOX_HORIZ_LINE] );
cur++;
topPos = HelpTell( helpFileHdl );
if( strnicmp( helpInBuf, ":eh", 3 ) == 0 ) {
getline();
}
}
*start = cur;
}
/*
* setupScroolBar - setup the size and position of the vertical scrollbar
*/
static void setupScrollBar( SAREA *use )
{
vGadget.start = use->row + 1;
vGadget.end = vGadget.start + use->height - 1;
vGadget.anchor = helpScreen.area.width + 1;
vGadget.win = &helpScreen;
vGadget.total_size = helpLines;
vGadget.page_size = use->height;
vGadget.pos = 0;
vGadget.slider = EV_SCROLL_VERTICAL;
uiinitgadget( &vGadget );
}
/*
* scrollHelp - refresh the displayed help after a scrolling operation
*/
static int scrollHelp( SAREA *use, int lastline, bool changecurr )
{
int useline;
int scroll;
int start;
int end;
scroll = currLine - lastline;
vscroll_fields( &helpTab, *use, scroll );
vvscroll( &helpScreen, *use, scroll );
currentAttr = AT( ATTR_NORMAL );
if( abs(scroll) >= use->height ) {
start = currLine;
end = start + use->height;
} else if( scroll < 0 ) {
start = currLine;
end = start - scroll;
} else {
start = currLine + use->height - scroll;
end = start + scroll;
}
seek_line( start );
for( ;; ++start ) {
save_line( start, HelpTell( helpFileHdl ) );
if( !getline() || strncmp( helpInBuf, "::::", 4 ) == 0 ) {
maxLine = start;
break;
}
useline = start - currLine;
if( useline >= use->height || start >= end ) {
break;
}
/* if it is the first time in,
then the old currfield is right
*/
processLine( helpInBuf, helpOutBuf, useline + use->row, changecurr );
putline( helpOutBuf, useline + use->row );
}
end = currLine + use->height;
if( maxLine != 0 && end > maxLine ) {
end = maxLine;
}
display_fields();
hotSpots[1].startcol = ( helpScreen.area.width - hotSpots[1].length )
/ 2;
addSearchButton( helpSearchHdl != NULL );
uiposnhotspots( &helpScreen, hotSpotFields );
uiprinthotspots( &helpScreen, hotSpotFields );
set_slider( currLine );
uirefresh();
return( currLine );
}
/*
* dispHelp
*/
static int dispHelp( char *str, VTAB *tab )
{
EVENT ev;
bool done;
int lastline;
int start;
SAREA use;
SAREA line;
char helpname[81];
ignoreMouseRelease = TRUE;
helpSet( str, helpname, sizeof( helpname ) );
if( uivopen( &helpScreen ) == NULL ) return( HELP_NO_VOPEN );
use.height = helpScreen.area.height - 3;
use.width = helpScreen.area.width;
use.col = 0;
line.height = 1;
line.width = helpScreen.area.width;
line.col = 0;
topPos = HelpTell( helpFileHdl );
getline();
handleHeader( &start, &line );
use.row = start;
use.height -= start;
handleFooter( &start, &use, &line );
setupScrollBar( &use );
if( helpLines > 0 ) {
maxPos = helpLines + 1;
helpPos = HelpMemAlloc( maxPos * sizeof(*helpPos) );
} else {
maxPos = 0;
helpPos = NULL;
}
maxLine = 0;
lastHelpLine = 0;
save_line( 0, topPos );
currLine = helpStack->line;
seek_line( currLine );
lastline = currLine + use.height;
done = FALSE;
ev = EV_NO_EVENT;
while( !done ) {
currentColour = C_PLAIN;
currentAttr = AT( ATTR_NORMAL );
if( lastline != currLine ) {
lastline = scrollHelp( &use, lastline, ev != EV_NO_EVENT );
}
ev = hlpwait( tab );
switch( ev ) {
case E_UP:
case EV_CURSOR_UP:
case EV_TOP:
if( currLine > 0 ) {
--currLine;
}
break;
case E_DOWN:
case EV_CURSOR_DOWN:
case EV_BOTTOM:
++currLine;
if( maxLine != 0 && currLine+use.height > maxLine ) {
--currLine;
}
break;
case EV_SCROLL_VERTICAL:
currLine = vGadget.pos;
break;
case EV_PAGE_UP:
currLine -= use.height;
if( currLine < 0 ) {
currLine = 0;
}
break;
case EV_PAGE_DOWN:
currLine += use.height;
if( maxLine != 0 && currLine >= maxLine ) {
currLine -= use.height;
}
break;
default:
done = TRUE;
break;
}
}
clearline();
uivclose( &helpScreen );
if( helpPos != NULL ) {
HelpMemFree( helpPos );
helpPos = NULL;
}
return( HELP_OK );
}
static int findhelp( VTAB *tab )
{
help_file *fileinfo;
int ret;
fileinfo = help_open( helpInBuf );
if( fileinfo == NULL ) {
return( HELP_NO_SUBJECT );
}
helpFileHdl = fileinfo->f;
helpSearchHdl = fileinfo->searchhdl;
ret = dispHelp( helpStack->word, tab );
/* if a new help file name exists,
then link to the new file
*/
if( helpTab != NULL && helpCur->key2_len != 0 ) {
curEvent = EV_ESCAPE;
}
return( ret );
}
/*
* fixHelpTopic - escape any special characters in topics that comes from
* the outside world
*/
static char *fixHelpTopic( char *topic )
{
char *ptr;
char *retptr;
unsigned cnt;
char *ret;
ptr = topic;
cnt = 0;
while( *ptr != '\0' ) {
if( *ptr == '<' || *ptr == '>' || *ptr == '"' || *ptr == '{'
|| *ptr == '}' ) {
cnt++;
}
cnt ++;
ptr ++;
}
ret = HelpMemAlloc( cnt + 1 );
retptr = ret;
ptr = topic;
while( *ptr != '\0' ) {
if( *ptr == '<' || *ptr == '>' || *ptr == '"' || *ptr == '{'
|| *ptr == '}' ) {
*retptr = HELP_ESCAPE;
retptr ++;
*retptr = *ptr;
} else {
*retptr = *ptr;
}
retptr++;
ptr++;
}
*retptr = '\0';
return( ret );
}
int showhelp( char *helptopic, EVENT (*rtn)( EVENT ), HelpLangType lang )
{
bool first;
int err;
char filename[_MAX_PATH];
char *hfiles[] = { NULL, NULL };
char ext[_MAX_EXT];
char *buffer;
first = TRUE;
err = FALSE;
switch( lang ) {
case HELPLANG_FRENCH:
hotSpots[0].str = "F4=Sujet pr俢俤ent";
hotSpots[1].str = "Sortir";
break;
case HELPLANG_ENGLISH:
break;
}
helpStack = NULL;
currentColour = C_PLAIN;
currentAttr = AT( ATTR_NORMAL );
/* initialize the tab filter */
tabFilter.tab = (unsigned (*)(void *,void *))help_in_tab;
tabFilter.next = (a_tab_field *(*)(void *,void *))help_next_field;
tabFilter.parm = helpTab;
tabFilter.mousepos = (void *(*)())uivmousepos;
tabFilter.mouseparm = &helpScreen;
tabFilter.first = helpTab;
tabFilter.wrap = FALSE;
tabFilter.enter = FALSE;
if( HelpFiles->name == NULL ) {
return( HELP_NO_FILE );
}
_splitpath( HelpFiles->name, NULL, NULL, filename, ext );
strcat( filename, ext );
hfiles[ 0 ] = filename;
while( ( helptopic != NULL || first ) ) {
if( first || help_reinit( hfiles ) ) {
err = do_showhelp( &helptopic, hfiles[0], rtn, first );
if( err == HELP_NO_SUBJECT ) break;
} else { // cannot open help file for hyperlink
buffer = HelpMemAlloc( 28 + strlen( hfiles[0] ) );
sprintf( buffer, "Unable to open helpfile \"%s\".", hfiles[0] );
ShowMsgBox( "Error", buffer );
HelpMemFree( buffer );
HelpMemFree( helptopic );
helptopic = HelpMemAlloc( strlen( helpStack->word ) + 1 );
strcpy( helptopic, helpStack->word );
strcpy( hfiles[0], helpStack->helpfname );
prevtopic();
}
first = FALSE;
}
return( err );
}
int do_showhelp( char **helptopic, char *filename, EVENT (*rtn)( EVENT ),
bool first )
{
int err;
char *ptr;
unsigned len;
char *htopic;
eventMapFn = rtn;
err = TRUE;
helpTab = NULL;
helpCur = helpTab;
strcpy( curFile, filename );
helpInBuf = HelpMemAlloc( BUF_LEN );
if( helpInBuf == NULL ) {
HelpMemFree( helpStack );
return( HELP_NO_MEM );
}
helpOutBuf = HelpMemAlloc( BUF_LEN );
if( helpOutBuf == NULL ) {
HelpMemFree( helpStack );
return( HELP_NO_MEM );
}
// don't fix hyperlink topics
if( *helptopic != NULL && first ) {
htopic = fixHelpTopic( *helptopic );
} else if( *helptopic == NULL ) {
len = 1;
htopic = HelpMemAlloc( len );
htopic[0] = '\0';
} else {
len = strlen( *helptopic );
htopic = HelpMemAlloc( len + 1 );
strcpy( htopic, *helptopic );
}
nexttopic( htopic );
for( ;; ) {
err = findhelp( &tabFilter );
if( err != HELP_OK ) break;
if( curEvent == EV_ESCAPE ) break;
if( curEvent == EV_KILL_UI ) break;
}
SearchDlgFini();
help_close();
// This is Not Nice - we're freeing memory that
// someone else allocated! Just don't do it.
if( err != HELP_NO_SUBJECT ) {
// HelpMemFree( *helptopic );
*helptopic = NULL;
*filename = '\0';
}
HelpMemFree( helpInBuf );
HelpMemFree( helpOutBuf );
HelpMemFree( htopic );
if( helpTab != NULL && helpCur->key2_len != 0 ) { // cross file link
*helptopic = HelpMemAlloc( helpCur->key1_len + 1 );
strncpy( *helptopic, helpCur->keyword, helpCur->key1_len );
(*helptopic)[ helpCur->key1_len ] = '\0';
ptr = &( helpCur->keyword[ helpCur->key1_len ] );
strncpy( filename, ptr, helpCur->key2_len );
filename[ helpCur->key2_len ] = '\0';
if( helpCur != tabFilter.curr ) { // backwards through cross file link
prevtopic();
}
} else {
Free_Stack();
}
free_fields( &helpTab );
return( err );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?