gen_cpp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,096 行 · 第 1/3 页
C
1,096 行
/****************************************************************************
*
* 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 <malloc.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include "global.h"
#include "types.h"
#include "sruinter.h"
#include "keywords.h"
#include "mem.h"
#include "error.h"
#include "options.h"
#include "ytab.gh"
#include "list.h"
#include "filelist.h"
static BOOL generateHeaderFile( sru_file *sru );
static void generateCoverFile( sru_file *sru );
static void generateCodeFile( sru_file *sru );
#define WIG_BEG_HEADER \
"// $PB$ -- begin generated code for object <%s>. Do not modify this code\n"
#define WIG_END_HEADER \
"// $PB$ -- end generated code for object <%s>.\n"
#define COVER_HEADER \
"/* This file is generated by PowerBuilder.\n"\
" * Do not modify this file.\n"\
" * This file contains interface code called by PowerBuilder.\n"\
" */ \n"
#define HPP_HEADER \
"/* This file contains code generated by PowerBuilder.\n"\
" * Do not modify code delimited by comments of the form:\n"\
" * "WIG_BEG_HEADER\
" * "WIG_END_HEADER\
" * This file contains the the C++ class definition for your user object.\n"\
" */ \n"\
"\n"\
"#include <string.hpp>\n"\
"#include <windows.h>\n"\
"\n"
#define CPP_HEADER \
"/* This file contains code generated by PowerBuilder.\n"\
" * Do not modify code delimited by comments of the form:\n"\
" * "WIG_BEG_HEADER\
" * "WIG_END_HEADER\
" * This file contains the bodies the functions for your user object.\n"\
" */ \n\n"
#define LIBMAIN_HEADER \
"/* This file is generated by PowerBuilder.\n"\
" * You may modify it in any way you wish but do not remove\n"\
" * Libmain and WEP. Without them you will be unable to link your DLL.\n"\
" */ \n"\
"\n"\
"#include <windows.h>\n"\
"#include \"pbdll.h\"\n\n"
#define DLLMAIN_FUNC \
"\n"\
"extern \"C\" {\n"\
"\n"\
"int __stdcall DLLMain( DWORD, DWORD reason, DWORD )\n"\
"{\n"\
" if( reason == DLL_PROCESS_ATTACH ) {\n"\
" extern char __WD_Present;\n"\
" if( __WD_Present ) { // this is a hook for the Watcom debugger.\n"\
" extern void Int3WithSignature( char __far * );\n"\
" #pragma aux Int3WithSignature parm caller [] = \\\n"\
" \"int 3\" \\\n"\
" \"jmp short L1\" \\\n"\
" 'W' 'V' 'I' 'D' 'E' 'O' \\\n"\
" \"L1:\"\n"\
" Int3WithSignature( \"DLL Loaded\" );\n"\
" }\n"\
" }\n"\
" return( 1 );\n"\
"}\n"\
"\n"\
"};\n\n"
#define LIBMAIN_FUNC \
"\n"\
"int PB_EXPORT LibMain( HANDLE, WORD, WORD, LPSTR )\n"\
"{\n"\
" return( 1 );\n"\
"}\n\n"
#define WEP_FUNC \
"int PB_EXPORT WEP( int )\n"\
"{\n"\
" return( 1 );\n"\
"}\n\n"
#ifndef MAX_PATH
#define MAX_PATH _MAX_PATH
#endif
#define SYSTEM_INCLUDE "\n#include <%s>\n"
#define PBDLL_H "pbdll.h"
#define THIS_HDL "this_hdl"
#define CLOSE_END " );\n"
#define TERM_START_FUNC " ) {\n"
#define CLOSE_SCOPE "}\n"
#define CLOSE_CLASS "};\n"
#define START_RETURN "return( "
#define START_CALL "this_hdl->%s( "
#define CLOSE_PAREN " )"
#define END_STATEMENT ";\n"
#define PARM_DECL "%s %s"
#define COMMA_DELIM ", "
#define SCOPE_EXTERN_C "\nextern \"C\" {\n"
#define INDENT " "
#define RETURN_ZERO " return( 0 );\n"
#define RETURN_NULL " return( (void*)0 );\n"
#define IF_TRUE "#if 1\n"
#define IF_FALSE "#if 0\n"
#define IF_NT "#ifdef __NT__\n"
#define ELSE "#else\n"
#define END_IF "#endif // PowerBuilder code, do not remove \n"
#define CONS_DECL_TMPLT "%s *PB_EXPORT %s();\n"
#define DES_DECL_TMPLT "void PB_EXPORT %s( %s *this_hdl );\n"
#define PBEXPORT_SRCH " PB_EXPORT "
#define PLACE_USER_CODE_HERE \
"//==================================\n"\
"\n"\
" /*\n"\
" * PUT YOUR CODE HERE\n"\
" */\n"\
"\n"
#define PLACE_DECLARATIONS_HERE \
"\n"\
" /*\n"\
" * PUT YOUR DECLARATIONS HERE\n"\
" */\n"\
"\n"
enum { /* type of function to create */
O_PROTOTYPE,
O_CLASS_PROTO,
O_FULL_FUNC,
O_CLASS_FUNC
};
enum { /* type of variable definition to create */
DATA_INSTANCE,
DATA_STATIC
};
typedef struct {
FILE *fp;
char *name;
} FileInfo;
#define LINE_SIZE 512
static char lineBuffer[LINE_SIZE];
static char lineBuffer2[LINE_SIZE];
static void genTmpFName( char *file, char *buf ) {
/*************************************************/
char fname[ _MAX_FNAME ];
char dir[ _MAX_DIR ];
char drive[ _MAX_DRIVE ];
unsigned i;
_splitpath( file, drive, dir, NULL, NULL );
for( i=0 ; i < 0x1000; i++ ) {
sprintf( fname, "TMP%03X", i );
_makepath( buf, drive, dir, fname, ".tmp" );
if( access( buf, F_OK ) ) break;
}
}
static void generateLibMain( void ) {
/*******************************/
FILE *fp;
char *fname;
fname = GetLmainName();
if( !access( fname, F_OK ) ) {
/* never overwrite this file if it exists */
return;
}
fp = WigOpenFile( fname, "wt" );
if( !fp ) {
Error( FILE_OPEN_ERR, fname );
}
if( fputs( LIBMAIN_HEADER, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( IF_NT, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( DLLMAIN_FUNC, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( ELSE, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( LIBMAIN_FUNC, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( WEP_FUNC, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
if( fputs( END_IF, fp ) == EOF ) Error( FILE_WRITE_ERR, fname );
WigCloseFile( fp );
}
void GenerateCPPFiles( sru_file *sru ) {
/*************************************/
assert( sru );
generateLibMain();
if( !(Options & OPT_GEN_C_CODE) ) {
if( !generateHeaderFile( sru ) ) return;
generateCoverFile( sru );
}
generateCodeFile( sru );
}
static void outInclude( FileInfo *fp ) {
/**************************************/
char fname[ _MAX_FNAME ];
char ext[ _MAX_EXT ];
assert( fp );
if( fprintf( fp->fp, SYSTEM_INCLUDE, PBDLL_H ) < 0 ) {
Error( FILE_WRITE_ERR, fp->name );
}
if( !(Options & OPT_GEN_C_CODE ) ) {
_splitpath( GetHeaderFile(), NULL, NULL, fname, ext );
if( fprintf( fp->fp, "\n#include \"%s%s\"\n", fname, ext ) < 0 ) {
Error( FILE_WRITE_ERR, fp->name );
}
}
}
#define MANGLE_LEN 4
#define NON_MANGLE_LEN ( PB_NAME_LEN - MANGLE_LEN )
void GenerateCoverFnName( char *uoname, char *fnname, char *buf ) {
/******************************************************************/
unsigned len1;
unsigned len2;
char mangle[MANGLE_LEN + 1];
char *tmpbuf;
len1 = strlen( uoname );
len2 = strlen( fnname );
if( len1 + len2 < NON_MANGLE_LEN ) {
strcpy( buf, uoname );
strcat( buf, fnname );
} else {
tmpbuf = alloca( len1 + len2 + 1 );
strcpy( tmpbuf, uoname );
strcpy( tmpbuf + len1, fnname );
GetHash( tmpbuf, mangle, MANGLE_LEN );
strncpy( buf, tmpbuf, NON_MANGLE_LEN );
strcpy( buf + NON_MANGLE_LEN, mangle );
}
}
static void outPutFunc( sp_header *sp, FileInfo *fp, char *class, int typ,
char *line ) {
/************************************/
/* Construct and spit out an appropriate function header */
var_rec *parm;
int len;
char buffer[100]; /* function proto buffer */
char fnname[ PB_NAME_LEN + 1 ];
assert( sp );
assert( fp );
assert( class );
/* if we could not determine any of its types, dont process it */
if( sp->fake ) {
return;
}
/* process beginning of function header */
parm = sp->parm_list;
switch( typ ) {
case( O_CLASS_PROTO ):
sprintf( buffer, "virtual %s %s( ", ConvertRetType( sp->typ_id ),
sp->name );
break;
case( O_PROTOTYPE ):
case( O_FULL_FUNC ):
GenerateCoverFnName( class, sp->name, fnname );
if( Options & OPT_GEN_C_CODE ) {
sprintf( buffer, "%s PB_EXPORT %s( ",
ConvertRetType( sp->typ_id ), fnname );
} else {
len = sprintf( buffer, "%s PB_EXPORT %s( %s *this_hdl",
ConvertRetType( sp->typ_id ), fnname, class );
if( parm && ( strcmp( parm->name, THIS_HDL ) || parm->next ) ) {
sprintf( buffer + len, COMMA_DELIM );
}
}
break;
case( O_CLASS_FUNC ):
sprintf( buffer, "%s %s::%s( ", ConvertRetType( sp->typ_id ), class,
sp->name);
break;
default:
assert( FALSE );
}
if( line ) {
strcpy( line, buffer );
}
if( fprintf( fp->fp, buffer ) < 0 ) {
Error( FILE_WRITE_ERR, fp->name );
}
/* remove the this_hdl parm from the list if necessary */
if( parm && !strcmp( parm->name, THIS_HDL ) ) {
parm = parm->next;
}
/* process the parameters */
while( parm ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?