⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem2str.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            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:  OS/2 String and Message table related semantic actions.
*
****************************************************************************/


#include <string.h>
#include "watcom.h"
#include "wresall.h"
#include "errors.h"
#include "global.h"
#include "rcmem.h"
#include "semantic.h"
#include "semstr.h"


extern int ResOS2WriteStringTableBlock( StringTableBlock *currblock,
                                        WResFileID handle, uint_32 codepage )
/***************************************************************************/
{
    int         stringid;
    int         error;
    WResIDName  *name;
    uint_16     tmp16;
    uint_8      tmp8;
    uint_8      tmpzero = 0;

    // Write string table codepage
    tmp16 = codepage;
    error = ResWriteUint16( &tmp16, handle );
    if( error )
        return( error );

    tmp16 = 1;

    for( stringid = 0, error = FALSE; stringid < STRTABLE_STRS_PER_BLOCK
                        && !error; stringid++ ) {
        name = currblock->String[ stringid ];
        if( name == NULL ) {
            // Write an empty string
            error = ResWriteUint16( &tmp16, handle );
        } else {
            // The string can't be longer than 255 chars
            tmp8  = (name->NumChars + 1) & 0xFF;
            error = ResWriteUint8( &tmp8, handle );
            if( !error )
                error = ResWriteStringLen( name->Name, FALSE, handle, tmp8 - 1 );
            // The terminating NULL is not stored in the table, need to add it now
            if( !error )
                error = ResWriteUint8( &tmpzero, handle );
        }
    }

    return( error );
} /* ResOS2WriteStringTableBlock */

extern FullStringTable *SemOS2NewStringTable( void )
/**************************************************/
{
    FullStringTable     *newtable;

    newtable = RcMemMalloc( sizeof( FullStringTable ) );
    if( newtable != NULL ) {
        newtable->Head = NULL;
        newtable->Tail = NULL;
        newtable->next = NULL;
        newtable->lang.lang = DEF_LANG;
        newtable->lang.sublang = DEF_SUBLANG;
    }

    return( newtable );
} /* SemOS2NewStringTable */

extern void SemOS2FreeStringTable( FullStringTable *oldtable )
/************************************************************/
{
    FullStringTableBlock        *currblock;
    FullStringTableBlock        *oldblock;

    currblock = oldtable->Head;
    while( currblock != NULL ) {
        ResFreeStringTableBlock( &(currblock->Block) );

        oldblock = currblock;
        currblock = currblock->Next;

        RcMemFree( oldblock );
    }

    RcMemFree( oldtable );
} /* SemOS2FreeStringTable */

static FullStringTableBlock *findStringTableBlock( FullStringTable *table,
                        uint_16 blocknum )
/************************************************************************/
{
    FullStringTableBlock        *currblock;

    for( currblock = table->Head; currblock != NULL;
                currblock = currblock->Next ) {
        if( currblock->BlockNum == blocknum)
            break;
    }

    return( currblock );
} /* findStringTableBlock */

static FullStringTableBlock *newStringTableBlock( void )
/******************************************************/
{
    FullStringTableBlock        *newblock;

    newblock = RcMemMalloc( sizeof( FullStringTableBlock ) );
    if( newblock != NULL ) {
        newblock->Next = NULL;
        newblock->Prev = NULL;
        newblock->BlockNum = 0;
        newblock->UseUnicode = (CmdLineParms.TargetOS == RC_TARGET_OS_WIN32);
        newblock->Flags = 0;
        newblock->codePage = 850;
        ResInitStringTableBlock( &(newblock->Block) );
    }

    return( newblock );
} /* newStringTableBlock */

extern void SemOS2AddStrToStringTable( FullStringTable *currtable,
                                 uint_16 stringid, char *string )
/****************************************************************/
{
    FullStringTableBlock        *currblock;
    uint_16                     blocknum;
    uint_16                     stringnum;

    blocknum = stringid >> 4;
    stringnum = stringid & 0x000f;

    currblock = findStringTableBlock( currtable, blocknum );
    if( currblock != NULL ) {
        if( currblock->Block.String[ stringnum ] != NULL ) {
            /* duplicate stringid */
            RcError( ERR_DUPLICATE_STRING_CONST, stringid );
            ErrorHasOccured = TRUE;
        }
    } else {
        currblock = newStringTableBlock();
        currblock->BlockNum = blocknum;
        ResAddLLItemAtEnd( (void **)&(currtable->Head), (void **)&(currtable->Tail), currblock );
    }

    currblock->Block.String[ stringnum ] = WResIDNameFromStr( string );
} /* SemAddStrToStringTable */

static void mergeStringTableBlocks( FullStringTableBlock *currblock,
                                FullStringTableBlock *oldblock )
/*******************************************************************/
{
    int     stringid;

    for( stringid = 0; stringid < STRTABLE_STRS_PER_BLOCK; stringid++ ) {
        if( currblock->Block.String[ stringid ] == NULL ) {
            currblock->Block.String[ stringid ] =
                                oldblock->Block.String[ stringid ];
            oldblock->Block.String[ stringid ] = NULL;
        } else {
            if( oldblock->Block.String[ stringid ] != NULL ) {
                RcError( ERR_DUPLICATE_STRING_CONST,
                            ( currblock->BlockNum << 4 ) + stringid );
                ErrorHasOccured = TRUE;
            }
        }
    }
} /* mergeStringTableBlocks */

static void semMergeStringTables( FullStringTable *currtable,
            FullStringTable *oldtable, ResMemFlags newblockflags,
            uint_32 codepage )
/****************************************************************/
/* merge oldtable into currtable and free oldtable when done */
/* returns TRUE if there was one or more duplicate entries */
{
    FullStringTableBlock        *currblock;
    FullStringTableBlock        *oldblock;
    FullStringTableBlock        *nextblock;

    /* run through the list of block in oldtable */
    oldblock = oldtable->Head;
    while( oldblock != NULL ) {
        /* find oldblock in currtable if it is there */
        nextblock = oldblock->Next;
        currblock = findStringTableBlock( currtable, oldblock->BlockNum );
        if( currblock == NULL ) {
            /* if oldblock in not in currtable move it there from oldtable */
            ResDeleteLLItem( (void **)&(oldtable->Head), (void **)&(oldtable->Tail), oldblock );
            oldblock->Flags = newblockflags;
            oldblock->codePage = codepage;
            ResAddLLItemAtEnd( (void **)&(currtable->Head), (void **)&(currtable->Tail), oldblock );
        } else {
            /* otherwise move the WSemID's to that block */
            mergeStringTableBlocks( currblock, oldblock );
        }
        oldblock = nextblock;
    }

    SemOS2FreeStringTable( oldtable );
} /* semMergeStringTables */

static void setStringTableFlags( FullStringTable *currtable,
                                ResMemFlags flags, uint_32 codepage )
/*******************************************************************/
{
    FullStringTableBlock    *currblock;

    for( currblock = currtable->Head; currblock != NULL;
                currblock = currblock->Next ) {
        currblock->Flags = flags;
        currblock->codePage = codepage;
    }
}

static void addTable( FullStringTable **tables, FullStringTable *newtable )
/*************************************************************************/
{
    while( *tables != NULL )
        tables = &( ( *tables )->next );

    *tables = newtable;
    newtable->next = NULL;
}

static FullStringTable *findTable( FullStringTable *tables )
/**********************************************************/
{
    return( tables );
}

extern void SemOS2MergeStrTable( FullStringTable *currtable,
                                    ResMemFlags flags, uint_32 codepage )
/***********************************************************************/
{
    FullStringTable     *table;

    table = findTable( CurrResFile.StringTable );
    if( table == NULL ) {
        setStringTableFlags( currtable, flags, codepage );
        addTable( &CurrResFile.StringTable, currtable );
    } else {
        semMergeStringTables( table, currtable, flags, codepage );
    }
}

extern void SemOS2MergeMsgTable( FullStringTable *currtable, ResMemFlags flags )
/******************************************************************************/
{
    FullStringTable     *table;

    table = findTable( CurrResFile.ErrorTable );
    if( table == NULL ) {
        setStringTableFlags( currtable, flags, SemOS2DefaultCodepage() );
        addTable( &CurrResFile.ErrorTable, currtable );
    } else {
        semMergeStringTables( table, currtable, flags, SemOS2DefaultCodepage() );
    }
}

extern void SemOS2WriteStringTable( FullStringTable *currtable, WResID *type )
/****************************************************************************/
/* write the table identified by currtable as a table of type type and then */
/* free the memory that it occupied */
{
    FullStringTableBlock    *currblock;
    FullStringTable         *tofree;
    WResID                  *name;
    int                     error;
    ResLocation             loc;

    while( currtable != NULL ) {
        for( currblock = currtable->Head; currblock != NULL;
                    currblock = currblock->Next ) {
            loc.start = SemStartResource();

            error = ResOS2WriteStringTableBlock( &(currblock->Block),
                                                 CurrResFile.handle,
                                                 currblock->codePage );
            if( error) {
                RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
                         LastWresErrStr() );
                ErrorHasOccured = TRUE;
                SemOS2FreeStringTable( currtable );
                return;
            }


            loc.len = SemEndResource( loc.start );
            /* +1 because WResID's can't be 0 */
            name = WResIDFromNum( currblock->BlockNum + 1 );
            SemAddResource( name, type, currblock->Flags, loc );
            RcMemFree( name );
        }

        tofree = currtable;
        currtable = currtable->next;
        SemOS2FreeStringTable( tofree );
    }
    RcMemFree( type );
    return;
}

⌨️ 快捷键说明

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