sorthelp.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 651 行 · 第 1/2 页

C
651
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  InfoBench help compiler mainline.
*
****************************************************************************/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdarg.h>
#include "uidef.h"
#include "stdui.h"
#include "help.h"
#include "cmdswtch.h"
#include "sorthelp.h"
#include "index.h"
#include "helpchar.h"
#include "helpmem.h"
#include "helpscan.h"

#define DEFTOPIC        "DEFTOPIC::::"
#define DESCRIPTION     "DESCRIPTION::::"

a_helpnode      *HelpNodes;

static bool     Verbose = FALSE;
static bool     GenIndex = TRUE;
static bool     GenStrings = TRUE;

static bool     pass1();
static bool     pass2();

static int      MaxCol = 78;
static int      MaxRow = 21;
static int      Width = 0;
static int      Height = 0;

#define BUFFER_SIZE     400

static char far UsageText[] = {
        "Usage: hcdos [flags] <infile> <outfile>\n"
    "\n"
    "\tflags:\n"
    "\t  -c <n>     maximum column allowed - default 78\n"
    "\t  -h <n>     force all windows # high\n"
    "\t  -n         don't generate an index for searching: don't use with -f\n"
    "\t  -r <n>     maximum row allowed - default 21\n"
    "\t  -v         verbose\n"
    "\t  -w <n>     force all windows # wide\n"
    "\t  -f{0,1,2}  outfile format \n"
    "\t             0: don't generate an index for searching (same as -n)\n"
    "\t             1: don't generate description and default topic strings\n"
    "\t             2: generate description and default topic strings (default)\n"
};

static FILE *errFile;
static char errFileName[_MAX_PATH];
static bool errHasOccurred;
static char errBuffer[512];

void Usage( void )
{
    fprintf( stderr, "%Ws", UsageText );
    exit( -1 );
}


void InitError( char *target )
{
    char    drive[_MAX_DRIVE];
    char    dir[_MAX_DIR];
    char    fname[_MAX_FNAME];

    errHasOccurred = FALSE;
    _splitpath( target, drive, dir, fname, NULL );
    _makepath( errFileName, drive, dir, fname, ".err" );
}


void FiniError( void )
{
    if( errFile != NULL ) {
        fclose( errFile );
    }
    if( !errHasOccurred ) {
        remove( errFileName );
    }
}

void PrintError( char *fmt, ... )
{
    va_list     al;

    if( !errHasOccurred ) {
        errFile = fopen( errFileName, "wt" );
        errHasOccurred = TRUE;
    }
    va_start( al, fmt );
    vsprintf( errBuffer, fmt, al );
    fputs( errBuffer, stderr );
    if( errFile != NULL ) {
        fputs( errBuffer, errFile );
    }
    va_end( al );
}

int main( int argc, char **argv )
{
    char        **nargv;
    char        **sargv;
    FILE        *fin;
    int         fout;
    char        *helpstr[2];
    bool        f_swtch;

    f_swtch = FALSE;
    helpstr[0] = NULL;
    helpstr[1] = NULL;
    for( argc=1, sargv=nargv=argv+1; *sargv; ++sargv ) {
        if( ! _IsCmdSwitch( *sargv ) ) {
            *nargv++ = *sargv;
            argc++;
        } else {
            switch( (*sargv)[1] ) {
            case 'n':
                GenIndex = FALSE;
                if( f_swtch ) {
                    PrintError( "More than one format switch found in command line\n" );
                    Usage();
                }
                f_swtch = TRUE;
                break;
            case 'v':
                Verbose = TRUE;
            break;
            case 'c':
                if( (*sargv)[2] != '\0' ) {
                    MaxCol = atoi( &(*sargv)[2] );
                } else {
                    if( *++sargv == NULL )
                        Usage();
                    MaxCol = atoi( *sargv );
                }
                break;
            case 'r':
                if( (*sargv)[2] != '\0' ) {
                    MaxRow = atoi( &(*sargv)[2] );
                } else {
                    if( *++sargv == NULL )
                        Usage();
                    MaxRow = atoi( *sargv );
                }
                break;
            case 'h':
                if( (*sargv)[2] != '\0' ) {
                    Height = atoi( &(*sargv)[2] );
                } else {
                    if( *++sargv == NULL )
                        Usage();
                    Height = atoi( *sargv );
                }
                break;
            case 'w':
                if( (*sargv)[2] != '\0' ) {
                    Width = atoi( &(*sargv)[2] );
                } else {
                    if( *++sargv == NULL )
                        Usage();
                    Width = atoi( *sargv );
                }
                break;
            case 'f':
                if( f_swtch ) {
                    PrintError( "More than one format switch found in command line\n" );
                    Usage();
                }
                f_swtch = TRUE;
                if( (*sargv)[2] == '0' ) {
                    GenIndex = FALSE;
                } else if( (*sargv)[2] == '1' ) {
                    GenStrings = FALSE;
                } else if( (*sargv)[2] == '2' ) {
                    GenStrings = TRUE;
                } else {
                    Usage();
                }
                break;
            default:
                Usage();
            break;
            }
        }
    }

    if( argc > 1  &&  strcmp( argv[1], "?" ) == 0 ) {
        Usage();
    }

    if( argc != 3 ) {
        Usage();
    }

    InitError( argv[1] );
    fin = fopen( argv[1], "rt" );
    if( fin == NULL ) {
        PrintError( "Unable to open '%s' for input\n", argv[1] );
        return( -1 );
    }

    fout = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
             S_IRWXU | S_IRWXG | S_IRWXO );
    if( fout == -1 ) {
        PrintError( "Unable to open '%s' for output\n", argv[2] );
        return( -1 );
    }

    pass1( fin, helpstr );
    pass2( fin, fout, helpstr );

    fclose( fin );
    close( fout );
    if( GenIndex ) {
        fout = open( argv[2], O_WRONLY | O_BINARY );
        WriteIndex( fout, helpstr, GenStrings );
        close( fout );
    }
    FiniError();
    HelpMemFree( helpstr[0] );
    HelpMemFree( helpstr[1] );
    return( 0 );
}

static void lineLenCB( TokenType type, void *info, unsigned *len )
{
    TextInfo        *text;
    TextInfoBlock   *block;
    HyperLinkInfo   *hyperlink;
    unsigned        i;

    switch( type ) {
    case TK_TEXT:
        text = info;
        switch( text->type ) {
        case TT_PLAIN:
        case TT_LEFT_ARROW:
        case TT_RIGHT_ARROW:
            *len += text->len;
            break;
        case TT_ESC_SEQ:
            *len += 1;
            break;
        }
        break;
    case TK_PLAIN_LINK:
        *len += 2;
    /* fall through */
    case TK_GOOFY_LINK:
        hyperlink = info;
        block = &( hyperlink->block1 );
        while( block != NULL ) {
            for( i=0; i < block->cnt; i++ ) {
            text = &( block->info[i] );
            switch( text->type ) {
            case TT_PLAIN:
                *len = text->len;
                break;
            case TT_ESC_SEQ:
                *len += 1;
                break;
            }
            }
            block = block->next;
        }
        break;
    }
}

static int line_len( char *str )
{
    unsigned    len;
    bool        newfile;

    len = 0;
    newfile = ScanLine( str, lineLenCB, &len );
    if( ( !GenIndex || !GenStrings ) && newfile ) {
        PrintError( "Cross file hyperlink in \"%s\" not supported with this format.\n", str );
    }
    return( len );
}

char *find_str( char *buf )
{
    int     len;
    char    *str;

    while( *buf != '"' ) {
        if( *buf == HELP_ESCAPE )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?