whpcvt.c

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

C
2,343
字号
/****************************************************************************
*
*                            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:  This program converts WHP files (WATCOM Help) into OS
*               dependent help files. Currently supported formats:
*
*                * Windows RTF
*                * OS/2 IPF
*                * DOS InfoBench Help (maybe)
*                * HTML
*                * MediaWiki tags
*
****************************************************************************/


#define WHPCVT_GBL
#include "whpcvt.h"

static const char *Help_info[] = {
    "Usage: whpcvt [options] <in_file> [<out_file>]",
    "   Options for all help file types:",
    "     -rtf     : generate Windows RTF output",
    "     -ipf     : generate OS/2 IPF output",
    "     -ib      : generate DOS InfoBench output",
    "     -html    : generate HTML output",
    "     -wiki    : generate wiki output",
    "     -@ <opt_file> : read more options from <opt_file> after the command line",
    "     -i       : generate <in_file>.idx file containing index of topics",
    "     -iw      : generate '.idx' file in WHP format (instead of GML)",
    "     -b       : generate <in_file>.blt file containing browse lists (GML)",
    "     -kw      : generate <in_file>.kw file containing keywords (GML)",
    "     -s       : sort browse lists",
    "     -h       : generate <in_file>.h topic define-const file",
    "     -hn      : read old <in_file>.h file to set new ctx numbers",
    "     -bl      : allow links to break across lines",
    "     -t       : generate <in_file>.tbl file containing table of contents",
    "     -e       : remove empty topics (except from table of contents)",
    "     -lk      : don't remove empty topics which have links to them",
    "     -kt      : don't add topic titles as search keywords",
    "     -mc      : use mixed case for generated topic titles (i.e. contents, etc.)",
    "     -dpt     : don't put popup topics in .tbl file",
    "     -dpk     : don't put popup topics in .kw file",
    "     -dpi     : don't put popup topics in .idx file",
    "     -dpb     : don't put popup topics in .blt file",
    "",
    "   Options for Windows RTF format:",
    "     -hh      : generate <in_file>.hh topic const file for help compiler",
    "     -up      : enable up topic support",
    "     -k       : keep titles in nonscrolling region at top",
    "     -xl      : initial indent for all lists",
    "     -dl      : initial indent for definition lists",
    "     -sl      : initial indent for simple lists",
    "     -ol      : initial indent for ordered lists",
    "     -ul      : initial indent for unordered lists",
    "",
    "   Options for OS/2 IPF & HTML format:",
    "     -rf      : use specified font types, not just system and courier",
    "     -ex      : exclude special topics",
    "     -tl \"title\" : sets a title for the help window. Put the title in quotes",
    "",
    "   Options for DOS InfoBench format:",
    "     -rm <n>  : set right margin to column <n>. Defaults to 76",
    "     -hd <f>  : include first line of file <f> in header",
    "     -ft <f>  : include first line of file <f> in footer",
    "     -tab <n> : set tab spacing to <n>. defaults to 4",
    "     -hb      : turns hyperlink bracing on",
    "     -up      : enable up topic support",
    "     -br      : enable browse button support",
    "     -tc      : enable contents button support",
    "     -ix      : enable index button support",
    "     -kb      : enable keyword button support",
    "     -dt \"topic\" : default topic",
    "     -ds \"desc\"  : description string for help file",
    "",
    "   You can specify \"-@ <opt_file>\" to put more options in a file",
    "       - Each option must be on a separate line",
    "   Default <in_file> extension is .whp",
    "   Default <out> extension is",
    "       for RTF:           " EXT_OUTRTF_FILE,
    "       for OS/2 IPF:      " EXT_OUTIPF_FILE,
    "       for Dos Infobench: " EXT_OUTIB_FILE,
    "       for HTML:          " EXT_OUTHTML_FILE,
    "       for wiki:          " EXT_OUTWIKI_FILE,
    NULL
};

enum {
    ARG_I,
    ARG_S,
    ARG_K,
    ARG_XL,
    ARG_DL,
    ARG_SL,
    ARG_OL,
    ARG_UL,
    ARG_H,
    ARG_HH,
    ARG_HN,
    ARG_B,
    ARG_UP,
    ARG_IW,
    ARG_RTF,
    ARG_IPF,
    ARG_BL,
    ARG_T,
    ARG_E,
    ARG_RF,
    ARG_LK,
    ARG_KT,
    ARG_IB,
    ARG_RM,
    ARG_HD,
    ARG_FT,
    ARG_TAB,
    ARG_HB,
    ARG_BR,
    ARG_TC,
    ARG_IX,
    ARG_KW,
    ARG_KB,
    ARG_TL,
    ARG_EX,
    ARG_MC,
    ARG_OF,
    ARG_DT,
    ARG_DS,
    ARG_DPT,
    ARG_DPK,
    ARG_DPI,
    ARG_DPB,
    ARG_HTML,
    ARG_WIKI,
    ARG_END
};

static char *Args[]={
    "i",
    "s",
    "k",
    "xl",
    "dl",
    "sl",
    "ol",
    "ul",
    "h",
    "hh",
    "hn",
    "b",
    "up",
    "iw",
    "rtf",
    "ipf",
    "bl",
    "t",
    "e",
    "rf",
    "lk",
    "kt",
    "ib",
    "rm",
    "hd",
    "ft",
    "tab",
    "hb",
    "br",
    "tc",
    "ix",
    "kw",
    "kb",
    "tl",
    "ex",
    "mc",
    "@",
    "dt",
    "ds",
    "dpt",
    "dpk",
    "dpi",
    "dpb",
    "html",
    "wiki",
    NULL
};

enum {
    TITLE_CASE_UPPER,
    TITLE_CASE_MIXED,
    TITLE_CASE_LAST,
};

enum {
    GEN_TITLE_CONTENTS,
    GEN_TITLE_INDEX,
    GEN_TITLE_KEYWORD,
    GEN_TITLE_BROWSE,
    GEN_TITLE_LAST,
};

static char *(Gen_titles[GEN_TITLE_LAST][TITLE_CASE_LAST])={
     { "Table of Contents",             "Table of contents"     },
     { "Index of Topics",               "Index of topics"       },
     { "Keyword Search",                "Keyword search"        },
     { "Browse Lists",                  "Browse lists"          }
};

/* File stuff */
static jmp_buf          Jmp_buf;
static int              Line_buf_size;
#define BUF_GROW        150

/* Processing globals */
static bool             Exclude_on=FALSE;
static char             Delim[3] = " \t";
static bool             Do_index=FALSE;
static bool             Do_blist=FALSE;
static bool             Do_keywords=FALSE;
static bool             Browse_sort=FALSE;
static bool             Do_def=FALSE;
static bool             Do_hdef=FALSE;
static bool             Do_ctx_ids = FALSE;
static bool             Do_contents=FALSE;
static bool             Index_gml_fmt=TRUE;
static int              Brace_count = 0;
static bool             Brace_check = FALSE;
static bool             Do_topic_keyword=TRUE;
static int              Title_case=TITLE_CASE_UPPER;
static bool             Dump_popup_t = FALSE;
static bool             Dump_popup_k = FALSE;
static bool             Dump_popup_i = FALSE;
static bool             Dump_popup_b = FALSE;
enum {
    OUT_RTF,
    OUT_IPF,
    OUT_IB,
    OUT_HTML,
    OUT_WIKI
};
static int              Output_type = OUT_RTF;


static char *Error_list[]={
    "Expecting topic definition, or topic section",
    "Context topic already exists",
    "A defined context topic must have a title",
    "Out of memory",
    "Bad cross-reference (hyperlink) or definition",
    "Maximum of 20 nested numbered lists allowed",
    "Cross-reference (hyperlink) to undefined topic",
    "Cross-reference (hyperlink) to an empty topic (use -lk option)",
    "Invalid number of parameters."
};

#define HELP_PREFIX     "HLP_"

static char *Chk_buf=NULL;

static char Output_file_ext[10];

char Help_fname[100];
char Header_File[100];
char Footer_File[100];

char *Options_file = NULL;

char Fonttype_roman[]="roman";
char Fonttype_symbol[]="symbol";
char Fonttype_helv[]="helv";
char Fonttype_courier[]="courier";

static ctx_def **Ctx_list_end=NULL;

static keyword_def *Keyword_list=NULL;
static int Keyword_id = 1;

static void print_help( void )
/****************************/
{
    const char                **p;

    for( p = Help_info; *p != NULL; ++p ) {
        printf( "%s\n", *p );
    }
}

void error_quit( void )
/*********************/
{
    longjmp( Jmp_buf, 1 );
}

void error_str(
/*************/

    char                *err_str
) {
    printf( "****%s\n", err_str );
    error_quit();
}

void error(
/*********/

    int                 err,
    bool                line_num
) {
    if( line_num ) {
        printf( "Error in input file on line %d.\n", Line_num );
    }
    error_str( Error_list[err] );
}

void error_line(
/**************/

    int                 err,
    int                 line_num
) {
    Line_num = line_num;

    error( err, TRUE );
}


void warning_str(
/***************/

    char                *warn_str
) {
    printf( "****%s\n", warn_str );
}

void warning(
/***********/

    int                 err,
    bool                line_num
) {
    if( line_num ) {
        printf( "Warning - in input file on line %d.\n", Line_num );
    }
    warning_str( Error_list[err] );
}

void warning_line(
/****************/

    int                 err,
    int                 line_num
) {
    Line_num = line_num;

    warning( err, TRUE );
}

void *check_alloc(
/****************/

    size_t              size
) {
    void                *p;

    p = malloc( size );

    if( p == NULL && size != 0) {
        error( ERR_NO_MEMORY, FALSE );
    }

    return( p );
}

void *check_realloc(
/******************/

    void                *ptr,
    size_t              size
) {
    ptr = realloc( ptr, size );

    if( ptr == NULL && size != 0 ) {
        error( ERR_NO_MEMORY, FALSE );
    }

    return( ptr );
}

static void check_brace(
/**********************/

    char                *buf,
    int                 len
) {
    char                *ptr;
    char                ch;
    char                prev_ch;

    if( Brace_check && Output_type == OUT_RTF ) {
        prev_ch = ' ';
        for( ptr = buf; len > 0; --len, ++ptr ) {
            ch = *ptr;
            if( ch == '{' && prev_ch != '\\' ) {
                ++Brace_count;
            } else if( ch == '}' && prev_ch != '\\' ) {
                --Brace_count;
            }
            prev_ch = ch;
        }
    }
}

void whp_fprintf(
/***************/

    FILE                *file,
    char                *fmt,
    ...
) {
    va_list             arglist;

    if( Chk_buf == NULL ) {
        _new( Chk_buf, 10000 );
    }

    if( Chk_buf != NULL ) {
        va_start( arglist, fmt );
        vsprintf( Chk_buf, fmt, arglist );
        check_brace( Chk_buf, strlen( Chk_buf ) );
        fputs( Chk_buf, file );
        va_end( arglist );
    }
}

void whp_fwrite(
/**************/

    char                *buf,
    int                 el_size,
    int                 num_el,
    FILE                *f
) {
    check_brace( buf, el_size * num_el );
    fwrite( buf, el_size, num_el, f );
}

static int process_args(
/**********************/

⌨️ 快捷键说明

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