srusuprt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,058 行 · 第 1/2 页
C
1,058 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <stdarg.h>
#include <assert.h>
#include "global.h"
#include "hashtab.h"
#include "srusuprt.h"
#include "sruinter.h"
#include "ytab.gh"
#include "mem.h"
#include "keywords.h"
#include "lexxer.h"
#include "gen_cpp.h"
#include "options.h"
#include "error.h"
#include "list.h"
#include "filelist.h"
static sru_file SRU;
static BOOL inSubPgm;
static BOOL setHeader;
#define PROTO_PRIME 257
#define OVERHEAD 16
/* required strings */
#define SRU_HEADER "PBExportHeader$"
#define THIS_VARIABLE "this_hdl"
#define THIS_TYPE "ulong"
#define DECL_THIS_VAR THIS_TYPE" "THIS_VARIABLE
#define LEFT_PAREN "( "
#define RIGHT_PAREN " )"
#define COMMA_DELIM ", "
#define RETURN_STATEMENT "return "
#define VARIABLE_SECTION "type variables\n"
#define END_VARIABLE_SECTION "end variables\n\n"
#define TYPE_PROTOTYPE_SECTION "type prototypes\n"
#define END_PROTOTYPE_SECTION "end prototypes\n\n"
#define FUNCTION "function "
#define SUBROUTINE "subroutine "
#define LIBRARY "library "
#define DLL_SUFFIX ".dll"
#define NONAME_FILE "noname"
#define REF_MODIFIER "ref "
#define DQUOTE "\""
#define CONSTRUCTOR_EVENT "constructor"
#define DESTRUCTOR_EVENT "destructor"
#define ON_CONSTRUCTOR "\non constructor\n"
#define ON_DESTRUCTOR "on destructor\n"
#define END_ON "end on\n\n"
#define DES_CALL_TEMPLATE "%s( this_hdl )\n"
#define CONS_CALL_TEMPLATE "this_hdl = %s( )\n"
#define DES_DECL_TEMPLATE "subroutine %s( ulong this_hdl ) library \"%s.dll\"\n"
#define CONS_DECL_TEMPLATE "function ulong %s( ) library \"%s.dll\"\n"
static statement *replaceStatement( statement *locale, char *stmt );
static statement *insertStatement( statement *locale, char *stmt );
static statement *appendStatement( char *stmt );
static void freeStatement( statement *curr );
void yyerror( char *msg ) {
/*************************/
msg = msg;
GetToEOS();
}
static id_type isTypeKnown( TypeInfo *typ ) {
/********************************************/
/* checks hash table to determine if a type is known and if it is, returns it id
*/
long len;
id_type rc;
keyword *tmp;
assert( typ );
len = strlen( typ->name );
tmp = FindHashEntry( SRU.typ_tab, HashString( typ->name, len ),
typ->name, len );
if( tmp ) {
rc = tmp->id;
if( typ->isref ) {
rc |= TY_REF_INDICATOR;
}
return( rc );
}
return( 0 );
}
static BOOL isConsDes( const char *name ) {
/*****************************************/
assert( name );
return( !stricmp( name, SRU.con_name ) || !stricmp( name, SRU.des_name ) );
}
void GetConstructor( char *uoname, char *buf ) {
/***********************************************/
GenerateCoverFnName( uoname, "_CPP_CONSTRUCTOR", buf );
}
void GetDestructor( char *uoname, char *buf ) {
/**********************************************/
GenerateCoverFnName( uoname, "_CPP_DESTRUCTOR", buf );
}
static void mkConsDesNames( void ) {
/**********************************/
/* puts together SRU constructor and destructor names */
int len;
char *classname;
classname = GetClass();
assert( classname );
if( SRU.con_name ) {
MemFree( SRU.con_name );
}
if( SRU.des_name ) {
MemFree( SRU.des_name );
}
len = strlen(classname);
SRU.con_name = MemMalloc( PB_NAME_LEN + 1 );
GetConstructor( classname, SRU.con_name );
SRU.des_name = MemMalloc( PB_NAME_LEN + 1 );
GetDestructor( classname, SRU.des_name );
}
void FreeSru( void ) {
/*********************/
statement *curr;
if( SRU.name ) {
MemFree( SRU.name );
}
if( SRU.con_name ) {
MemFree( SRU.con_name );
}
if( SRU.name ) {
MemFree( SRU.des_name );
}
while( SRU.head_stmt ) {
curr = SRU.head_stmt;
SRU.head_stmt = curr->next;
freeStatement( curr );
}
DestroyHashTable( SRU.type_prots );
DestroyHashTable( SRU.typ_tab );
memset( &SRU, 0, sizeof( sru_file ) ); /* clear all records */
}
void InitSru( void ) {
/********************/
long x;
memset( &SRU, 0, sizeof( sru_file ) );
inSubPgm = FALSE;
setHeader = FALSE;
SRU.type_prots = NewHashTable( PROTO_PRIME );
SRU.name = MemStrDup( NONAME_FILE );
SetDefaultAccess( ST_PUBLIC );
SetBaseName( SRU.name );
if( Options & OPT_GEN_C_CODE ) {
SRU.flags |= CONSTRUCTOR_DEFINED;
SRU.flags |= DESTRUCTOR_DEFINED;
}
mkConsDesNames();
/* loads types into hash table */
SRU.typ_tab = NewHashTable( HASH_PRIME );
x = 0;
while( DataTypes[x].key != NULL ) {
InsertHashValue( SRU.typ_tab, DataTypes[x].key,
strlen( DataTypes[x].key ), &DataTypes[x] );
x++;
}
}
void SetDefaultAccess( id_type type ) {
/**************************************/
if( inSubPgm ) {
return;
}
SRU.curr_access = type;
}
void SetHeader( char *name, char *ext ) {
/***************************************/
unsigned headerlen;
ext = ext;
headerlen = strlen( SRU_HEADER );
if( inSubPgm || setHeader || strnicmp(name, SRU_HEADER, headerlen ) ) {
return;
}
assert( name );
assert( ext );
setHeader = TRUE;
if( SRU.name ) {
MemFree( SRU.name );
}
SRU.name = MemStrDup( name );
strcpy( SRU.name, name + headerlen );
SetBaseName( SRU.name );
mkConsDesNames();
}
void UserCode( void ) {
/*********************/
if( !inSubPgm ) {
return;
}
SRU.subprog->data.sp.user_code++;
}
void SetComment( void ) {
/***********************/
if( !inSubPgm ) {
return;
}
SRU.subprog->data.sp.user_code++; /* do not put any WIG code in */
}
void SetReturn( void ) {
/**********************/
if( !inSubPgm ) {
return;
}
SRU.flags |= RETURN_STMT_PRESENT;
}
static void copyTypeInfo( TypeInfo *dst, TypeInfo *src ) {
/*********************************************************/
if( src->name == NULL ) {
dst->name = NULL;
} else {
dst->name = MemStrDup( src->name );
}
dst->isref = src->isref;
}
void SetFunction( TypeInfo *ret, char *fname ) {
/***********************************************/
if( inSubPgm ) {
return;
}
assert( fname );
assert( ret );
copyTypeInfo( &( SRU.curr.sp.ret_type ), ret );
SRU.curr.sp.name = MemStrDup( fname );
SRU.curr.sp.typ = ST_FUNCTION;
SRU.curr_typ = SRU_SUBPROG;
SRU.curr.sp.typ_id = isTypeKnown( ret ); /* we must first set sp info */
if( !SRU.curr.sp.typ_id ) {
/* issue warning if unknown type is found and set fake bit */
/* only issue a warning for forward definitions so we don't issue
* the same warning twice */
if( SRU.sections->data.sec.primary == ST_FORWARD ) {
Warning( UNKNOWN_TYPE, ret->name, fname );
}
SRU.curr.sp.fake = TRUE;
}
}
void SetSubroutine( char *sname ) {
/*********************************/
if( inSubPgm ) {
return;
}
assert( sname );
SRU.curr.sp.ret_type.name = NULL;
SRU.curr.sp.ret_type.isref = FALSE;
SRU.curr.sp.name = MemStrDup( sname );
SRU.curr.sp.typ = ST_SUBROUTINE;
SRU.curr.sp.subroutine = TRUE;
SRU.curr_typ = SRU_SUBPROG;
}
void StartSubProgram( void ) {
/****************************/
/* do some house cleaning before we start processing subprograms */
if( inSubPgm || SRU.sections ) {
return;
}
if( SRU.var_sec == NULL && !(Options & OPT_GEN_C_CODE) ) {
SRU.var_sec = appendStatement( VARIABLE_SECTION );
appendStatement( END_VARIABLE_SECTION );
}
if( SRU.type_sec == NULL ) {
SRU.type_sec = appendStatement( TYPE_PROTOTYPE_SECTION );
appendStatement( END_PROTOTYPE_SECTION );
}
}
void EndSubProgram( void ) {
/**************************/
/* determine wether to munge the current subprogram to make an
external call, and then closes this subprogram
*/
char *line;
var_rec *finger;
int size;
char *ret;
char *name;
statement *curr;
if( !inSubPgm ) {
return;
}
inSubPgm = FALSE;
assert( SRU.subprog );
/* determine whether we should munge the subprogram */
if( SRU.subprog->data.sp.user_code > 1 ) {
return;
} else if( !(SRU.subprog->data.sp.typ_id && SRU.subprog->data.sp.ret_stmt)
&& SRU.subprog->data.sp.user_code ) {
return;
}
/* munge subprogram */
/* calculate size of statement */
name = SRU.subprog->data.sp.name;
size = strlen( name );
size += sizeof(LEFT_PAREN) + sizeof(RIGHT_PAREN) + sizeof(THIS_VARIABLE);
finger = SRU.subprog->data.sp.parm_list;
while( finger ) {
size += strlen( finger->name ) + sizeof( COMMA_DELIM );
finger = finger->next;
}
if( !SRU.subprog->data.sp.subroutine ) {
size += sizeof( RETURN_STATEMENT );
}
/* allocate memory and create function call */
line = alloca( size );
if( !SRU.subprog->data.sp.subroutine ) {
ret = RETURN_STATEMENT;
} else {
ret = "";
}
finger = SRU.subprog->data.sp.parm_list;
if( Options & OPT_GEN_C_CODE ) {
sprintf( line, "%s%s%s", ret, name, LEFT_PAREN );
} else {
sprintf( line, "%s%s%s%s", ret, name, LEFT_PAREN, THIS_VARIABLE );
if( finger ) {
strcat( line, COMMA_DELIM );
}
}
while( finger ) {
strcat( line, finger->name );
if( finger->next ) {
strcat( line, COMMA_DELIM );
}
finger = finger->next;
}
strcat( line, RIGHT_PAREN );
strcat( line, "\n" );
/* determine where to place the new call, and place it there */
if( SRU.subprog->data.sp.typ_id && (SRU.subprog->data.sp.user_code == 1) &&
SRU.subprog->data.sp.ret_stmt ) {
curr = SRU.subprog;
while( curr && ( curr->next != SRU.subprog->data.sp.ret_stmt ) ) {
curr = curr->next;
}
if( curr ) {
replaceStatement( curr, line );
} else {
insertStatement( SRU.subprog, line );
}
} else {
insertStatement( SRU.subprog, line );
}
}
void FiniParmList( void ) {
/*************************/
/* currently we do nothing */
}
void AddParm( TypeInfo *typ, char *tname, ArrayInfo *array ) {
/*************************************************************/
/* add parameter to current function's list */
var_rec *ptmp;
if( inSubPgm ) {
return;
}
assert( tname );
assert( typ );
ptmp = MemMalloc( sizeof( var_rec ) );
memset( ptmp, 0, sizeof( var_rec ) );
if( SRU.curr.sp.last_parm ) {
SRU.curr.sp.last_parm->next = ptmp;
} else {
SRU.curr.sp.parm_list = ptmp;
}
SRU.curr.sp.last_parm = ptmp;
copyTypeInfo( &ptmp->type, typ );
ptmp->typ_id = isTypeKnown( typ );
if( !ptmp->typ_id ) {
ptmp->fake = TRUE;
}
ptmp->next = NULL;
ptmp->name = MemStrDup( tname );
if( array == NULL ) {
ptmp->array = NULL;
} else {
ptmp->array = MemMalloc( sizeof( ArrayInfo ) );
memcpy( ptmp->array, array, sizeof( ArrayInfo ) );
}
}
void StartSection( id_type ptyp, id_type styp ) {
/***********************************************/
if( inSubPgm ) {
return;
}
SRU.curr.sec.primary = ptyp;
SRU.curr.sec.secondary = styp;
SRU.curr_typ = SRU_SECTION;
if( styp == ST_VARIABLES ) {
if( ptyp == ST_SHARED ) {
SetDefaultAccess( ST_PRIVATE );
} else if( ptyp == ST_TYPE ) {
SetDefaultAccess( ST_PUBLIC );
}
}
}
void EndSection(void) {
/*********************/
if( inSubPgm ) {
return;
}
if( SRU.sections ) {
SRU.sections = SRU.sections->link;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?