whpcvt.c

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

C
2,343
字号
    ctx_def             *old_ctx;
    int                 title_fmt;
    int                 head_level;
    char                *ptr;
    char                ch, o_ch;
    int                 i;

    Delim[0] = CH_CTX_DEF;
    ptr = strtok( Line_buf + 1, Delim );
    head_level = atoi( ptr );
    ctx_name = strtok( NULL, Delim );

    title_fmt = TITLE_FMT_DEFAULT;
    if( *ctx_name == CH_TOPIC_LN ) {
        title_fmt = TITLE_FMT_LINE;
        ++ctx_name;
    } else if( *ctx_name == CH_TOPIC_NOLN ) {
        title_fmt = TITLE_FMT_NOLINE;
        ++ctx_name;
    }
    ctx = find_ctx( ctx_name );
    old_ctx = ctx;
    if( ctx != NULL && ctx->title != NULL ) {
        if(( head_level != 0 ) && ( ctx->head_level != 0 )) {
            printf( "topic already exists: %s\n", ctx_name );
            warning( ERR_CTX_EXISTS, TRUE );
        }
        for( i = 0; i < strlen( ctx_name ); ++i ) {
            o_ch = ctx_name[i];
            for( ch = 'A'; ch < 'Z'; ++ch ) {
                ctx_name[i] = ch;
                if( find_ctx( ctx_name ) == NULL ) {
                    break;
                }
            }
            if( ch != 'Z' ) {
                ctx = NULL;
                break;
            }
            ctx_name[i] = o_ch;
        }
    }

    title = strtok( NULL, Delim );
    if( title == NULL ) {
        error( ERR_NO_TITLE, TRUE );
    }

    browse_name = strtok( NULL, Delim );
    if( browse_name != NULL ) {
        keywords = strtok( NULL, Delim );
    } else {
        keywords = NULL;
    }

    if( ctx == NULL ) {
        ctx = init_ctx( ctx_name );
    }
    ctx->title_fmt = title_fmt;
    add_ctx( ctx, title, keywords, browse_name, head_level );

    if(( old_ctx != NULL )
      && ( old_ctx != ctx )
      && ( old_ctx->head_level == 0 )) {
        ptr = old_ctx->ctx_name;
        old_ctx->ctx_name = ctx->ctx_name;
        ctx->ctx_name = ptr;
    }

    return( ctx );
}

static bool read_ctx_def( void )
/******************************/
{
    return( read_topic_text( define_ctx(), TRUE, 0 ) );
}

static bool read_ctx_topic( void )
/********************************/
{
    char                *ctx_name;
    ctx_def             *ctx;
    char                *order_str;

    Delim[0] = CH_TOPIC;
    ctx_name = strtok( Line_buf, Delim );

    ctx = find_ctx( ctx_name );

    if( ctx == NULL ) {
        ctx = init_ctx( ctx_name );
        add_ctx( ctx, NULL, NULL, NULL, -1 );
    }
    Curr_ctx = ctx;

    order_str = strtok( NULL, Delim );
    if( order_str == NULL ) {
        return( read_topic_text( ctx, TRUE, 0 ) );
    } else {
        return( read_topic_text( ctx, FALSE, atoi( order_str ) ) );
    }
}

static bool read_topic( void )
/****************************/
{
    switch( Line_buf[0] ) {

    case CH_CTX_DEF:
        return( read_ctx_def() );

    case CH_TOPIC:
        return( read_ctx_topic() );

    case ' ':
    case '\t':
    case '\0':
        if( *skip_blank( Line_buf ) == '\0' ) {
            /* due to a bug on GML, skip completely blank lines
               between topics, like this */
            return( read_line() );
        }
        /* DROP INTO DEFAULT CASE */

    default:
        error( ERR_NO_TOPIC, TRUE );    // does not return
    }

    return( FALSE );
}

static void read_whp_file( void )
/*******************************/
{
    if( !read_line() ) {
        return;
    }
    for( ;; ) {
        if( !read_topic() ) {
            break;
        }
    }
}

static void set_browse_numbers( void )
/************************************/
{
    browse_def                  *browse;
    browse_ctx                  *b_ctx;
    int                         order;

    for( browse = Browse_list; browse != NULL; browse = browse->next ) {
        order = 1;
        for( b_ctx = browse->ctx_list; b_ctx != NULL; b_ctx = b_ctx->next ) {
            b_ctx->ctx->browse_num = order;
            ++order;
        }
    }
}

static void sort_ctx_list( void )
/*******************************/
{
    ctx_def                     *ctx;
    ctx_def                     *sort_list;
    ctx_def                     **sort_spot;
    ctx_def                     *next_ctx;
    char                        buf[100];

    sort_list = NULL;
    for( ctx = Ctx_list; ctx != NULL; ctx = next_ctx ) {
        next_ctx = ctx->next;
        if( ctx->title == NULL ) {
            /* ctx item without a definition */
            sprintf( buf, "The context id '%s' is used but not defined",
                                                            ctx->ctx_name );
            error_str( buf );
        }
        for( sort_spot = &sort_list; *sort_spot != NULL;
                                        sort_spot = &((*sort_spot)->next) ) {
            if( stricmp( skip_prep( ctx->title ),
                                skip_prep( (*sort_spot)->title ) ) < 0 ) {
                break;
            }
        }
        ctx->next = *sort_spot;
        *sort_spot = ctx;
    }
    Ctx_list = sort_list;
}

bool is_special_topic(
/********************/

    ctx_def                     *ctx,
    bool                        dump_popup
) {
    bool                        res;

    if( ctx == NULL ) {
        res = FALSE;
    } else {
        res = ( stricmp( ctx->ctx_name, "table_of_contents" ) == 0 ||
                stricmp( ctx->ctx_name, "index_of_topics" ) == 0 ||
                stricmp( ctx->ctx_name, "keyword_search" ) == 0 ||
                stricmp( ctx->ctx_name, "browse_lists" ) == 0  ||
                ( ctx->title_fmt == TITLE_FMT_NOLINE && dump_popup ) );
    }
    return( res );
}

static void output_idx_file( void )
/*********************************/
{
    char                        ch;
    ctx_def                     *ctx;
    char                        *sort_title;
    char                        pfx[20];
    bool                        new_topic;

    ch = 0;
    if( Index_gml_fmt ) {
        whp_fprintf( Idx_file, ":H1.%s\n",
                                Gen_titles[GEN_TITLE_INDEX][Title_case] );
    } else {
        whp_fprintf( Idx_file, "%s:\n\n",
                                Gen_titles[GEN_TITLE_INDEX][Title_case] );
    }
    new_topic = FALSE;
    for( ctx = Ctx_list; ctx != NULL; ctx = ctx->next ) {
        if( ctx->empty ||
                ( Dump_popup_i && ctx->title_fmt == TITLE_FMT_NOLINE ) ) {
            continue;
        }
        sort_title = skip_prep( ctx->title );
        if( ch != toupper( *sort_title ) ) {
            if( Index_gml_fmt ) {
                if( ch == 0 ) {
                    sprintf( pfx, "%c\n:pb.", CH_DLIST_START );
                } else {
                    strcpy( pfx, ":p." );
                }
                ch = toupper( *sort_title );
                whp_fprintf( Idx_file, "%s%c- %c -\n",
                                    pfx, CH_DLIST_TERM, ch );
                new_topic = TRUE;
            } else {
                ch = toupper( *sort_title );
                whp_fprintf( Idx_file, "- %c -\n", ch );
            }
        }
        if( Index_gml_fmt ) {
            whp_fprintf( Idx_file, ":pb." );
            if( new_topic ) {
                whp_fprintf( Idx_file, "%c", CH_DLIST_DESC );
                new_topic = FALSE;
            }
            whp_fprintf( Idx_file, "%c%s%c%s%c\n",
                CH_HLINK, ctx->ctx_name, CH_HLINK, ctx->title, CH_HLINK );
        } else {
            whp_fprintf( Idx_file, "    %c%s%c%s%c\n",
                CH_HLINK, ctx->ctx_name, CH_HLINK, ctx->title, CH_HLINK );
        }
    }
    if( ch != 0 && Index_gml_fmt ) {
        whp_fprintf( Idx_file, ":pb.%c\n\n", CH_DLIST_END );
    }
}

static int kw_cmp(
/****************/

    const void          *_kw1,
    const void          *_kw2
) {
    keyword_def **kw1 = (keyword_def**)_kw1;
    keyword_def **kw2 = (keyword_def**)_kw2;

    return( stricmp( (*kw1)->keyword, (*kw2)->keyword ) );
}

static int ctx_cmp(
/****************/

    const void          *_ctx1,
    const void          *_ctx2
) {
    ctx_def **ctx1 = (ctx_def**)_ctx1;
    ctx_def **ctx2 = (ctx_def**)_ctx2;

    return( stricmp( (*ctx1)->title, (*ctx2)->title ) );
}

// removes empty contexts from a given keyword_def if Remove_empty == TRUE
static void compress_kw(
/**********************/

    keyword_def                 *kw
) {
    int                         o_size;
    int                         n_size=0;
    int                         o_idx = 0;
    int                         n_idx = 0;

    if( Remove_empty ) {
        o_size = kw->ctx_list_size;

        while( o_idx < o_size ) {
            if( !kw->ctx_list[o_idx]->empty ) {
                kw->ctx_list[n_idx] = kw->ctx_list[o_idx];
                n_idx++;
                n_size++;
            }
            o_idx++;
        }

        kw->ctx_list_size = n_size;
    }
}

static void output_kw_file( void )
/********************************/
{
    keyword_def                 *temp_kw;   // used for grabbing keywords
    keyword_def                 **kw;       // array of *keyword_def's
    ctx_def                     **ctx;      // array of *ctx_def's
    int                         ctx_num;    // number of ctx we're on
    int                         kw_num = 0; // number of keywords
    int                         i;          // counter
    bool                        title;      // whether we've printed this kw

    // output header
    whp_fprintf( KW_file, ":H1.%s\n",
                                Gen_titles[GEN_TITLE_KEYWORD][Title_case] );
    whp_fprintf( KW_file, ":pb.%cc\n", CH_SLIST_START );

    // count the number of keywords in our list
    temp_kw = Keyword_list;
    while( temp_kw !=NULL ) {
        kw_num++;
        temp_kw = temp_kw->next;
    }

    // if we've got any keywords ...
    if( kw_num > 0 ) {
        // ... we allocate an array of pointers to keywords ...
        _new( kw, kw_num );

        // ... fill it up ...
        kw_num = 0;
        temp_kw = Keyword_list;
        while( temp_kw !=NULL ) {
            kw[kw_num] = temp_kw;
            kw_num++;
            temp_kw = temp_kw->next;
        }

        // .. and then sort it.
        qsort( kw, kw_num, sizeof(keyword_def *), kw_cmp );

        for( i = 0; i < kw_num; i++ ) {
            title = FALSE;

            // remove empty contexts if we need to
            compress_kw( kw[i] );

            // get our array of contexts
            ctx = kw[i]->ctx_list;
            ctx_num = 0;

            // we treat keywords with only one context as a special case
            if( kw[i]->ctx_list_size == 1 ) {
                if( !is_special_topic( ctx[ctx_num], Dump_popup_k ) ) {
                    if( kw[i]->ctx_list_size == 1 ) {
                        whp_fprintf( KW_file,
                                    ":pb.%c:pb.%c%s%c%s%c\n",
                                    CH_LIST_ITEM,
                                    CH_HLINK,
                                    ctx[ 0 ]->ctx_name,
                                    CH_HLINK,
                                    kw[i]->keyword,
                                    CH_HLINK );
                    }
                }
            } else if( kw[i]->ctx_list_size >1 ) {
                // sort the list of contexts by title.
                qsort( ctx, kw[i]->ctx_list_size, sizeof(ctx_def *),
                                                                ctx_cmp );

                while( ctx_num < kw[i]->ctx_list_size ) {
                    // if the context is not special output a hyperlink
                    if( !is_special_topic( ctx[ctx_num], Dump_popup_k ) ) {
                        if( !title ) {
                            // output keyword
                            whp_fprintf( KW_file,
                                        ":pb.%c:pb.%cb%c%s%c\n"
                                        ":pb.%cc\n",

                                        CH_LIST_ITEM,
                                        CH_FONTSTYLE_START,
                                        CH_FONTSTYLE_START,
                                        kw[i]->keyword,
                                        CH_FONTSTYLE_END,

                                        CH_SLIST_START );
                            title = TRUE;
                        }
                        whp_fprintf( KW_file, ":pb.%c%c%s%c%s%c\n",
                                CH_LIST_ITEM,
                                CH_HLINK,
                                ctx[ ctx_num ]->ctx_name,
                                CH_HLINK,
                                ctx[ ctx_num ]->title,
                                CH_HLINK );
                    }
                    // go to the next context on our list
                    ctx_num++;
                }
                if( title ) {
                    whp_fprintf( KW_file,
                                ":pb.%c\n",

                                CH_SLIST_END );
                }
            }
        }
    }

    // the end
    whp_fprintf( KW_file, ":pb.%c\n", CH_SLIST_END );
}

static void output_blist_file( void )
/***********************************/
{
    browse_def                  *browse;
    browse_ctx                  *b_ctx;
    browse_ctx                  *b_ctx_next;
    ctx_def                     *ctx;
    char                        *pfx;

    whp_fprintf( Blist_file, ":H1.%s\n%c\n",
                Gen_titles[GEN_TITLE_BROWSE][Title_case], CH_DLIST_START );
    pfx = ":pb.";
    for( browse = Browse_list; browse != NULL; browse = browse->next ) {
        for( ctx = Ctx_list; ctx != NULL; ctx = ctx->next ) {
            if( stricmp( ctx->title, browse->browse_name ) == 0 ) {
                break;
            }
        }
        if( ctx != NULL ) {
            if( is_special_topic( ctx, Dump_popup_b ) ) {
                /* kludge fix to make life easier for the FET books */
                continue;
            }

            whp_fprintf( Blist_file, "%s%c%cb%c%c%s%c%s%c%c\n",
                        pfx, CH_DLIST_TERM, CH_FONTSTYLE_START,
                        CH_FONTSTYLE_START, CH_HLINK, ctx->ctx_name,
                        CH_HLINK, ctx->title, CH_HLINK, CH_FONTSTYLE_END );
        } else {
            whp_fprintf( Blist_file, "%s%c%s\n", pfx, CH_DLIST_TERM,
                                                    browse->browse_name );
        }
        pfx = ":p.";

        whp_fprintf( Blist_file, ":pb.%c", CH_DLIST_DESC );
        for( b_ctx = browse->ctx_list; ; ) {

⌨️ 快捷键说明

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