ipf.c

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

C
757
字号
/****************************************************************************
*
*                            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 file defines the IPF specific functions.
*
****************************************************************************/

#include "whpcvt.h"

static int Curr_head_level = 0;
static int Curr_head_skip = 0;

#define BOX_LINE_SIZE   200

#define FONT_STYLE_BOLD         1
#define FONT_STYLE_ITALIC       2
#define FONT_STYLE_UNDERLINE    4

static char     *Font_match[]={
    ":hp1.:ehp1",               // 0: PLAIN
    ":hp2.",                    // 1: BOLD
    ":hp1.",                    // 2: ITALIC
    ":hp3.",                    // 3: BOLD + ITALIC
    ":hp5.",                    // 4: UNDERLINE
    ":hp7.",                    // 5: BOLD + UNDERLINE
    ":hp6.",                    // 6: ITALIC + UNDERLINE
    ":hp7.",                    // 7: BOLD + ITALIC + UNDERLINE (can't do it)
};

static char     *Font_end[]={
    "",                         // 0: PLAIN
    ":ehp2.",                   // 1: BOLD
    ":ehp1.",                   // 2: ITALIC
    ":ehp3.",                   // 3: BOLD + ITALIC
    ":ehp5.",                   // 4: UNDERLINE
    ":ehp7.",                   // 5: BOLD + UNDERLINE
    ":ehp6.",                   // 6: ITALIC + UNDERLINE
    ":ehp7.",                   // 7: BOLD + ITALIC + UNDERLINE (can't do it)
};

static int Font_list[100];      // up to 100 nested fonts
static int Font_list_curr= 0;

static bool Blank_line_pfx=FALSE;
static bool Blank_line_sfx=TRUE;

#define IPF_TRANS_LEN           50

static char *Trans_str=NULL;
static int Trans_len=0;

#define MAX_TABS                100     // up to 100 tab stops
static int Tab_list[MAX_TABS];

static void draw_line(
/********************/

    section_def         *section,
    int                 *alloc_size
) {
    int                 i;

    trans_add_str( ":cgraphic.\n", section, alloc_size );
    for( i = BOX_LINE_SIZE; i > 0; --i ) {
        trans_add_char( 196, section, alloc_size );
    }
    trans_add_str( "\n:ecgraphic.\n", section, alloc_size );
}

static int translate_char_ipf(
/****************************/

    char                ch,
    char                *buf
) {
    switch( ch ) {

    case ':':
        strcpy( buf,  "&colon." );
        break;

    case '=':
        strcpy( buf, "&eq." );
        break;

    case '&':
        strcpy( buf, "&amp." );
        break;

    case '.':
        strcpy( buf, "&per." );
        break;

    default:
        buf[0] = ch;
        buf[1] = '\0';
        break;
    }

    return( strlen( buf ) );
}

static char *translate_str_ipf(
/*****************************/

    char                *str
) {
    char                *t_str;
    int                 len;
    char                buf[IPF_TRANS_LEN];
    char                *ptr;

    len = 1;
    for( t_str = str; *t_str != '\0'; ++t_str ) {
        len += translate_char_ipf( *t_str, buf );
    }
    if( len > Trans_len ) {
        if( Trans_str != NULL ) {
            _free( Trans_str );
        }
        _new( Trans_str, len );
        Trans_len = len;
    }
    ptr = Trans_str;
    for( t_str = str; *t_str != '\0'; ++t_str ) {
        len = translate_char_ipf( *t_str, buf );
        strcpy( ptr, buf );
        ptr += len;
    }
    *ptr = '\0';

    return( Trans_str );
}

static int trans_add_char_ipf(
/****************************/

    char                ch,
    section_def         *section,
    int                 *alloc_size
) {
    char                buf[IPF_TRANS_LEN];

    translate_char_ipf( ch, buf );
    return( trans_add_str( buf, section, alloc_size ) );
}

static int trans_add_str_ipf(
/***************************/

    char                *str,
    section_def         *section,
    int                 *alloc_size
) {
    int                 len;

    len = 0;
    for( ; *str != '\0'; ++str ) {
        len += trans_add_char_ipf( *str, section, alloc_size );
    }

    return( len );
}

static int trans_add_list(
/************************/

    char                *list,
    section_def         *section,
    int                 *alloc_size,
    char                *ptr
) {
    int                 len;

    len = trans_add_str( list, section, alloc_size );
    ++ptr;
    if( *ptr == 'c' ) {
        len += trans_add_str( " compact", section, alloc_size );
    }

    len += trans_add_str( ".\n", section, alloc_size );

    return( len );
}

static void read_tabs(
/********************/

    char                *tab_line
) {
    char                *ptr;
    int                 i;
    int                 tabcol;

    Tab_xmp_char = *tab_line;

    ptr = strtok( tab_line + 1, " " );
    for( tabcol = 0, i = 0 ; ptr != NULL; ptr = strtok( NULL, " " ), ++i ) {
        if( *ptr == '+' ) {
            tabcol += atoi( ptr + 1 );
        } else {
            tabcol = atoi( ptr );
        }
        Tab_list[i] = tabcol;
    }
    Tab_list[i] = -1;
}

static int tab_align(
/*******************/

    int                 ch_len,
    section_def         *section,
    int                 *alloc_size
) {
    int                 i;
    int                 len;

    // find the tab we should use
    i = 0;
    while( ch_len >= Tab_list[i]) {
        if( Tab_list[i] == -1 ) break;
        ++i;
    }

    len = 1;
    if( Tab_list[i] != -1 ) {
        len =  Tab_list[i] - ch_len;
    }
    for( i = len; i > 0; --i ) {
        trans_add_char_ipf( ' ', section, alloc_size );
    }

    return( len );
}

void ipf_topic_init(
/******************/

    void
) {
}

int ipf_trans_line(
/*****************/

    section_def         *section,
    int                 alloc_size
) {
    char                *ptr;
    char                *end;
    char                ch;
    char                *ctx_name;
    char                *ctx_text;
    char                buf[500];
    int                 font_idx;
    int                 line_len;
    bool                term_fix;
    int                 ch_len;
    int                 len;
    char                *file_name;

    /* check for special column 0 stuff first */
    ptr = Line_buf;
    ch = *ptr;
    ch_len = 0;
    line_len = 0;

    switch( ch ) {

    case CH_TABXMP:
        if( *skip_blank( ptr + 1 ) == '\0' ) {
            Tab_xmp = FALSE;
            trans_add_str( ":exmp.\n", section, &alloc_size );
            Blank_line_sfx = FALSE;     // remove following blanks
        } else {
            read_tabs( ptr + 1 );
            trans_add_str( ":xmp.\n", section, &alloc_size );
            Tab_xmp = TRUE;
            Blank_line_pfx = FALSE;     // remove preceding blanks
        }
        return( alloc_size );

    case CH_BOX_ON:
        /* Table support is the closest thing to boxing in IPF, but it
           doesn't work well with changing fonts on items in the tables
           (the edges don't line up). So we draw long lines at the
           top and bottom instead */
        draw_line( section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_BOX_OFF:
        draw_line( section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_START:
        trans_add_list( ":ol", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_LIST_START:
        trans_add_list( ":ul", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_DLIST_START:
        trans_add_str( ":dl break=all tsize=5.\n", section, &alloc_size );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_START:
        trans_add_list( ":sl", section, &alloc_size, ptr );
        Blank_line_pfx = FALSE;
        return( alloc_size );

    case CH_SLIST_END:
        trans_add_str( ":esl.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_OLIST_END:
        trans_add_str( ":eol.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_END:
        trans_add_str( ":eul.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_DLIST_END:
        trans_add_str( ":edl.\n", section, &alloc_size );
        Blank_line_sfx = FALSE;
        return( alloc_size );

    case CH_LIST_ITEM:
    case CH_DLIST_TERM:
        /* eat blank lines before list items and terms */
        Blank_line_pfx = FALSE;
        break;

    case CH_CTX_KW:
        ptr = whole_keyword_line( ptr );
        if( ptr == NULL ) {
            return( alloc_size );
        }
        break;
    }

    if( *skip_blank( ptr ) == '\0' ) {
        /* ignore blanks lines before the topic starts */
        if( !Curr_ctx->empty ) {
            /* the line is completely blank. This tells us to output
               a blank line. BUT, all lists and things automatically

⌨️ 快捷键说明

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