📄 semantic.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: Semantic actions called by the YACC generated driver.
*
****************************************************************************/
#include <stdio.h> /* remove call for MS format stuff */
#include <string.h>
#include <ctype.h>
#include "wresall.h"
#include "errors.h"
#include "rcmem.h"
#include "rcio.h" /* semantic.c uses the RcTmpFileName function */
#include "global.h"
#include "ytab.gh"
#include "semantic.h"
#include "tmpctl.h"
static WResLangType curLang;
static int resourceHasLang;
static WResLangType resourceLang;
/* used in the work around for MS format RES files */
static int MSFormatHandle; /* holding place for the RES file handle */
static char MSFormatTmpFile[ _MAX_PATH ] = "";
/* Modified from WINNT.H */
#ifndef MAKELANGID
#define MAKELANGID(p, s) ((((uint_16)(s)) << 10) | (uint_16)(p))
#endif
void SetDefLang( void ) {
/*************************/
curLang.lang = DEF_LANG;
curLang.sublang = DEF_SUBLANG;
}
void SemSetGlobalLanguage( WResLangType *newlang ) {
/*******************************************************************/
if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
curLang = *newlang;
} else {
RcWarning( ERR_NT_KEYWORD, SemTokenToString( Y_LANGUAGE ) );
}
}
void SemSetResourceLanguage( WResLangType *newlang, int from_parser ) {
/**********************************************************************/
if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
resourceHasLang = TRUE;
resourceLang = *newlang;
} else if( from_parser ) {
RcWarning( ERR_NT_KEYWORD, SemTokenToString( Y_LANGUAGE ) );
}
}
WResLangType GetResourceLanguage( void ) {
/******************************************/
if( resourceHasLang ) {
return( resourceLang );
} else {
return( curLang );
}
}
void ClearResourceLanguage( void ) {
/***********************************/
resourceHasLang = FALSE;
}
void SemUnsupported( uint_8 token ) {
/***********************************/
RcWarning( ERR_UNSUPPORTED, SemTokenToString( token ) );
}
SemOffset SemStartResource( void )
/********************************/
{
if( StopInvoked ) {
RcFatalError( ERR_STOP_REQUESTED );
}
if (CurrResFile.IsWatcomRes) {
return( ResTell( CurrResFile.handle ) );
} else {
/* open a temporary file and trade handles with the RES file */
RcTmpFileName( MSFormatTmpFile );
MSFormatHandle = CurrResFile.handle;
CurrResFile.handle = MResOpenNewFile( MSFormatTmpFile );
if (CurrResFile.handle == -1) {
CurrResFile.handle = MSFormatHandle;
ResCloseFile( CurrResFile.handle );
remove( CurrResFile.filename );
RcFatalError( ERR_OPENING_TMP, MSFormatTmpFile, LastWresErrStr() );
} else {
RegisterTmpFile( MSFormatTmpFile );
CurrResFile.filename = MSFormatTmpFile;
}
/* The start position should be 0 but to be safe call ResTell */
return( ResTell( CurrResFile.handle ) );
}
}
SemLength SemEndResource( SemOffset start )
/*****************************************/
{
SemLength len;
if (CurrResFile.IsWatcomRes) {
return( ResTell( CurrResFile.handle ) - start );
} else {
/* Close the temperary file, reset the RES file handle and return */
/* the length of the resource */
len = ResTell( CurrResFile.handle ) - start;
if( ResCloseFile( CurrResFile.handle ) == -1 ) {
RcError( ERR_CLOSING_TMP, CurrResFile.filename, LastWresErrStr() );
ErrorHasOccured = TRUE;
}
CurrResFile.handle = MSFormatHandle;
CurrResFile.filename = CurrResFile.namebuf;
return( len );
}
}
void SemAddResourceFree( WResID * name, WResID * type, ResMemFlags flags,
ResLocation loc )
/***********************************************************************/
{
SemAddResource2( name, type, flags, loc, NULL );
RcMemFree( name );
RcMemFree( type );
}
static void copyMSFormatRes( WResID * name, WResID * type, ResMemFlags flags,
ResLocation loc, WResLangType *lang )
/***************************************************************************/
{
MResResourceHeader ms_head;
long cur_byte_num;
uint_8 cur_byte;
long seek_rc;
int error;
int tmp_handle;
/* fill in and output a MS format resource header */
ms_head.Type = WResIDToNameOrOrd( type );
ms_head.Name = WResIDToNameOrOrd( name );
ms_head.MemoryFlags = flags;
ms_head.Size = loc.len;
ms_head.LanguageId = MAKELANGID( lang->lang, lang->sublang );
ms_head.Version = 0L; /* Currently Unsupported */
ms_head.DataVersion = 0L;
ms_head.Characteristics = 0L; /* Currently Unsupported */
/* OS/2 resource header happens to be identical to Win16 */
if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ||
CmdLineParms.TargetOS == RC_TARGET_OS_OS2 ) {
error = MResWriteResourceHeader( &ms_head, CurrResFile.handle, FALSE );
} else {
error = MResWriteResourceHeader( &ms_head, CurrResFile.handle, TRUE );
}
if (error) {
RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
LastWresErrStr() );
RcMemFree( ms_head.Type );
RcMemFree( ms_head.Name );
ErrorHasOccured = TRUE;
} else {
RcMemFree( ms_head.Type );
RcMemFree( ms_head.Name );
tmp_handle = ResOpenFileRO( MSFormatTmpFile );
if (tmp_handle == -1) {
RcError( ERR_OPENING_TMP, MSFormatTmpFile, LastWresErrStr() );
ErrorHasOccured = TRUE;
return;
}
/* copy the data from the temperary file to the RES file */
seek_rc = ResSeek( tmp_handle, loc.start, SEEK_SET );
if (seek_rc == -1) {
RcError( ERR_READING_TMP, MSFormatTmpFile, LastWresErrStr() );
ResCloseFile( tmp_handle );
ErrorHasOccured = TRUE;
return;
}
/* this is very inefficient but hopefully the buffering in layer0.c */
/* will make it tolerable */
for (cur_byte_num = 0; cur_byte_num < loc.len; cur_byte_num++) {
error = ResReadUint8( &cur_byte, tmp_handle );
if( error ) {
RcError( ERR_READING_TMP, MSFormatTmpFile, LastWresErrStr() );
ResCloseFile( tmp_handle );
ErrorHasOccured = TRUE;
return;
} else {
error = ResWriteUint8( &cur_byte, CurrResFile.handle );
if( error ) {
RcError( ERR_WRITTING_RES_FILE,
CurrResFile.filename, LastWresErrStr() );
ResCloseFile( tmp_handle );
ErrorHasOccured = TRUE;
return;
}
}
}
if( ResCloseFile( tmp_handle ) == -1 ) {
RcError( ERR_WRITTING_RES_FILE, MSFormatTmpFile,
LastWresErrStr() );
ErrorHasOccured = TRUE;
}
}
}
void SemAddResource( WResID * name, WResID * type, ResMemFlags flags,
ResLocation loc )
/**********************************************************************/
{
SemAddResource2( name, type, flags, loc, NULL );
}
void SemAddResource2( WResID * name, WResID * type, ResMemFlags flags,
ResLocation loc, char *filename )
/******************************************************************/
{
int error;
int duplicate;
char * namestr;
WResLangType *lang;
if( resourceHasLang ) {
lang = &resourceLang;
resourceHasLang = FALSE;
} else {
lang = &curLang;
}
// Windows 95 is currently unable to load an exe that contains a resource
// with numeric type or numeric identifier greater than 0x7FFF
// so we warn the user
if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
if( !type->IsName && type->ID.Num > 0x7FFF ) {
namestr = WResIDToStr( name );
RcWarning( ERR_TYPE_GT_7FFF, namestr );
RcMemFree( namestr );
}
if( !name->IsName && name->ID.Num > 0x7FFF ) {
namestr = WResIDToStr( name );
RcWarning( ERR_NAME_GT_7FFF, namestr );
RcMemFree( namestr );
}
}
error = WResAddResource( type, name, flags, loc.start, loc.len,
CurrResFile.dir, lang, &duplicate );
if (duplicate) {
if( filename == NULL ) {
ReportDupResource( name, type, NULL, NULL, TRUE );
} else {
ReportDupResource( name, type, filename, CmdLineParms.InFileName,
TRUE );
}
/* The resource has already been written but we can't add it to */
/* directory. This will make the .RES file larger but will otherwise */
/* not affect it since there will be no references to the resource in */
/* the directory. */
} else if (error) {
RcError( ERR_OUT_OF_MEMORY );
ErrorHasOccured = TRUE;
}
if (!CurrResFile.IsWatcomRes) {
if (!duplicate) {
copyMSFormatRes( name, type, flags, loc, lang );
}
/* erase the temporary file */
remove( MSFormatTmpFile );
UnregisterTmpFile( MSFormatTmpFile );
MSFormatTmpFile[0] = '\0';
}
}
FullMemFlags SemAddFirstMemOption( uint_8 token )
/***********************************************/
{
FullMemFlags newflags;
newflags.flags = 0;
newflags.loadOptGiven = FALSE;
newflags.memOptGiven = FALSE;
newflags.purityOptGiven = FALSE;
return( SemAddMemOption( newflags, token ) );
}
FullMemFlags SemAddMemOption( FullMemFlags currflags, uint_8 token )
/******************************************************************/
{
switch (token) {
case Y_PRELOAD:
currflags.flags |= MEMFLAG_PRELOAD;
currflags.loadOptGiven = TRUE;
break;
case Y_LOADONCALL:
currflags.flags &= ~MEMFLAG_PRELOAD;
currflags.loadOptGiven = TRUE;
break;
case Y_FIXED:
currflags.flags &= ~MEMFLAG_MOVEABLE;
currflags.memOptGiven = TRUE;
break;
case Y_MOVEABLE:
currflags.flags |= MEMFLAG_MOVEABLE;
currflags.memOptGiven = TRUE;
break;
case Y_DISCARDABLE:
currflags.flags |= MEMFLAG_DISCARDABLE;
currflags.memOptGiven = TRUE;
break;
case Y_PURE:
currflags.flags |= MEMFLAG_PURE;
currflags.purityOptGiven = TRUE;
break;
case Y_IMPURE:
currflags.flags &= ~MEMFLAG_PURE;
currflags.purityOptGiven = TRUE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -