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

📄 sem2menu.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 Menu related semantic actions.
*
****************************************************************************/


/*

The data structure for OS/2 MENU resources is as follows:

struct MenuHeader {
    ULONG  cbSize;          // Size of menu/submenu including this field
    USHORT idCodePage;      // Menu codepage
    USHORT idClass;         // Window class ID (always WC_MENU?)
    USHORT cItems;          // Number of menu items that follow
}

struct MenuItem {
    USHORT flStyle;         // Menu style flags
    USHORT fAttributes;     // Menu attribute flags
    USHORT cmd;             // Menu item ID
    CHAR   szItemName[];    // Null-terminated menu text (none for separator)
}

*/


#include <string.h>
#include "wresall.h"
#include "errors.h"
#include "global.h"
#include "rcmem.h"
#include "ytab2.gh"
#include "semantic.h"
#include "semmenu.h"


#include "reserr.h"

int ResOS2WriteMenuHeader( MenuHeaderOS2 *currhead, WResFileID handle )
/*********************************************************************/
{
    int     numwrote;

    numwrote = WRESWRITE( handle, currhead, sizeof(MenuHeaderOS2) );
    if( numwrote != sizeof(MenuHeaderOS2) ) {
        WRES_ERROR( WRS_WRITE_FAILED );
        return( TRUE );
    } else {
        return( FALSE );
    }
}

int ResOS2WriteMenuItemNormal( const MenuItemOS2 *curritem, WResFileID handle )
/*****************************************************************************/
{
    int         error;
    uint_16     tmp16;

    tmp16 = curritem->ItemStyle;
    error = ResWriteUint16( &tmp16, handle );
    if( !error ) {
        tmp16 = curritem->ItemAttrs;
        error = ResWriteUint16( &tmp16, handle );
    }
    if( !error ) {
        tmp16 = curritem->ItemCmd;
        error = ResWriteUint16( &tmp16, handle );
    }
    if( !error ) {
        if( !(curritem->ItemStyle & OS2_MIS_SEPARATOR) && curritem->ItemText != NULL )
            error = ResWriteString( curritem->ItemText, FALSE, handle );
    }

    return( error );
}

static void SemOS2FreeSubMenu( FullMenuOS2 *submenu );

MenuFlags SemOS2AddFirstMenuOption( uint_8 token )
/************************************************/
{
    return( SemOS2AddMenuOption( 0, token ) );
}

MenuFlags SemOS2AddMenuOption( MenuFlags oldflags, uint_8 token )
/***************************************************************/
{
    switch( token ) {
    case Y_BITMAP:
        oldflags |= MENU_BITMAP;
        break;
    }

    return( oldflags );
}

FullMenuOS2 *SemOS2NewMenu( FullMenuItemOS2 firstitem )
/*****************************************************/
{
    FullMenuOS2       *newmenu;
    FullMenuItemOS2   *newitem;

    newmenu = RcMemMalloc( sizeof(FullMenuOS2) );
    newitem = RcMemMalloc( sizeof(FullMenuItemOS2) );

    if( newmenu == NULL || newitem == NULL ) {
        RcError( ERR_OUT_OF_MEMORY );
        ErrorHasOccured = TRUE;
        return( NULL );
    }

    *newitem = firstitem;
    newmenu->head = NULL;
    newmenu->tail = NULL;

    ResAddLLItemAtEnd( (void **)&(newmenu->head), (void **)&(newmenu->tail), newitem );

    return( newmenu );
}

FullMenuOS2 *SemOS2AddMenuItem( FullMenuOS2 *currmenu, FullMenuItemOS2 curritem )
/*******************************************************************************/
{
    FullMenuItemOS2     *newitem;

    newitem = RcMemMalloc( sizeof(FullMenuItemOS2) );

    if (newitem == NULL) {
        RcError( ERR_OUT_OF_MEMORY );
        ErrorHasOccured = TRUE;
        return( NULL );
    }

    *newitem = curritem;

    ResAddLLItemAtEnd( (void **)&(currmenu->head), (void **)&(currmenu->tail), newitem );

    return( currmenu );
}

static int SemOS2WriteMenuItem( FullMenuItemOS2 *item, int *err_code )
/********************************************************************/
{
    int     error;

    error = ResOS2WriteMenuItemNormal( &(item->item), CurrResFile.handle );
    *err_code = LastWresErr();
    return( error );
}

static int SemOS2CalcSubMenuSize( FullMenuOS2 *submenu, int *count )
/******************************************************************/
{
    FullMenuItemOS2 *curritem;
    int             size = 0, dummycount;

    size += sizeof( MenuHeaderOS2 );

    if( submenu == NULL ) {
        return( size );
    }

    for( curritem = submenu->head; curritem != NULL; curritem = curritem->next ) {
        *count += 1;
        size += 3 * sizeof(uint_16);
        if( !(curritem->item.ItemStyle & OS2_MIS_SEPARATOR) &&
            curritem->item.ItemText != NULL )
            size += strlen( curritem->item.ItemText ) + 1;
        if( curritem->submenu != NULL ) {
            size += SemOS2CalcSubMenuSize( curritem->submenu, &dummycount );
        }
    }
    return( size );
}


static int SemOS2WriteSubMenu( FullMenuOS2 *submenu, int *err_code,
                               uint_32 codepage )
/******************************************************************/
{
    int             error, count = 0;
    FullMenuItemOS2 *curritem;
    MenuHeaderOS2   head;

    if( ErrorHasOccured ) {
        return( FALSE );
    }

    head.Size     = SemOS2CalcSubMenuSize( submenu, &count );
    head.Codepage = codepage;
    head.Class    = 4;
    head.NumItems = count;

    error = ResOS2WriteMenuHeader( &head, CurrResFile.handle );
    if( error ) {
        ErrorHasOccured = TRUE;
        return( error );
    }

    if( submenu == NULL ) {
        return( error );
    }

    for( curritem = submenu->head, error = FALSE; curritem != NULL && !error;
                curritem = curritem->next ) {
        if( !ErrorHasOccured ) {
            error = SemOS2WriteMenuItem( curritem, err_code );
            if( !error && (curritem->submenu != NULL) ) {
                error = SemOS2WriteSubMenu( curritem->submenu, err_code, codepage );
            }
        }
    }

    if( error ) {
        ErrorHasOccured = TRUE;
    }
    return( error );
}

static void SemOS2FreeMenuItem( FullMenuItemOS2 *curritem )
/*********************************************************/
{
    if( curritem->submenu != NULL ) {
        SemOS2FreeSubMenu( curritem->submenu );
        if (curritem->item.ItemText != NULL) {
            RcMemFree( curritem->item.ItemText );
        }
    } else {
        if( curritem->item.ItemText != NULL ) {
            RcMemFree( curritem->item.ItemText );
        }
    }
}

static void SemOS2FreeSubMenu( FullMenuOS2 *submenu )
/***************************************************/
{
    FullMenuItemOS2   *curritem;
    FullMenuItemOS2   *olditem;

    if( submenu != NULL ) {
        curritem = submenu->head;
        while( curritem != NULL ) {
            SemOS2FreeMenuItem( curritem );
            olditem = curritem;
            curritem = curritem->next;
            RcMemFree( olditem );
        }

        RcMemFree( submenu );
    }
}

void SemOS2WriteMenu( WResID *name, ResMemFlags flags, FullMenuOS2 *menu,
                   uint_16 tokentype, uint_32 codepage )
/***********************************************************************/
{
    ResLocation     loc;
    int             error;
    int             err_code;

    if( !ErrorHasOccured ) {
        loc.start = SemStartResource();
        error = SemOS2WriteSubMenu( menu, &err_code, codepage );
        if( error ) {
            err_code = LastWresErr();
            goto OutputWriteError;
        }
        loc.len = SemEndResource( loc.start );
        SemAddResourceFree( name, WResIDFromNum( OS2_RT_MENU ), flags, loc );
    } else {
        RcMemFree( name );
    }

    SemOS2FreeSubMenu( menu );
    return;

OutputWriteError:
    RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
             strerror( err_code ) );
    ErrorHasOccured = TRUE;
    SemOS2FreeSubMenu( menu );
    return;
}

⌨️ 快捷键说明

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