conv.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,792 行 · 第 1/4 页
C
1,792 行
/****************************************************************************
*
* 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: Generate *.obj and *.asm thunks for interfacing from
* WIN386 (32-bit flat) to 16-bit Windows API function
* (16-bit segmented). It uses Pharlap Easy OMF (32-bit)
* for *.obj thunks.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define MAX_BUFF 256
/*
* depth into stack from which to get parms: 3 dwords pushed
*/
#define STACK_FRAME 3*4+4
char line[] = ";****************************************************************************\n";
char blank[] = ";*** ***\n";
char GlueInc[] = "winglue.inc";
int genstubs = 0;
int quiet = 0;
typedef enum {
PARM_PTR,
PARM_WORD,
PARM_DWORD,
PARM_VOID,
PARM_DOUBLE
} parm_types;
typedef enum {
RETURN_PTR,
RETURN_INT,
RETURN_CHAR,
RETURN_DWORD,
RETURN_VOID
} return_types;
struct subparm {
struct subparm *nextparm;
unsigned offset;
unsigned parmnum;
};
/*
* data structure containing all data about a prototype
*/
typedef struct fcn {
struct fcn *next; /* link */
char *fn; /* function name */
char *plist; /* parameter list */
struct subparm *subparms; /* sub parms that need aliasing */
int class; /* what class it belongs to */
struct fcn *next_class;/* connects to next function in same class */
char pcnt; /* number of parms */
char returntype; /* function return type */
char aliascnt; /* number of 16-bit aliases to be created */
unsigned thunkindex:5; /* ThunkStrs index */
unsigned thunk:1; /* requires a thunking layer */
unsigned is_16:1; /* is an _16 function */
unsigned is_tinyio:1; /* is a tinyio function */
unsigned noregfor_16:1; /* _16 function has no regular function */
unsigned need_fpusave:1; /* function requires floating point save */
unsigned __special_func:1;/* special @func requires extra thunking */
} fcn;
struct parmlist {
struct parmlist *next;
char parm_count;
char alias_count;
char parm_types[1];
};
char **ThunkStrs;
char * ThunkGenerated;
int ThunkIndex;
int MaxAliasCount;
struct parmlist *ParmList;
fcn *Class, *CurrClass; /* class list */
fcn *Head, *Curr; /* list of all prototypes */
fcn *VoidHead, *VoidCurr; /* list of all prototypes */
void *myalloc( size_t size )
{
void *tmp;
tmp = calloc( 1, size );
if( tmp == NULL ) {
printf("Out of Memory!\n");
exit( 1 );
}
return( tmp );
} /* myalloc */
void *_fmyalloc( size_t size )
{
void *tmp;
tmp = malloc( size );
if( tmp == NULL ) {
printf("Out of Memory!\n");
exit( 1 );
}
memset( tmp, 0, size );
return( tmp );
} /* _fmyalloc */
void *_fmyrealloc( void *ptr, size_t size )
{
void *tmp;
tmp = realloc( ptr, size );
if( tmp == NULL ) {
printf("Out of Memory!\n");
exit( 1 );
}
return( tmp );
} /* _fmyrealloc */
int IsWord( char *str )
{
if( !stricmp( str,"int" ) ||
!stricmp( str,"char" ) ||
!stricmp( str,"unsigned char" ) ||
!stricmp( str,"short" ) ||
!stricmp( str,"unsigned" ) ||
!stricmp( str,"unsigned short" ) ||
!stricmp( str,"unsigned int" ) ) {
return( 1 );
}
return( 0 );
} /* IsWord */
/*
* StripSpaces - remove leading and trailing spaces
*/
static char *StripSpaces( char *buff )
{
int i;
i = strlen( buff ) - 1;
while( buff[i] == ' ' ) {
buff[i--] = '\0';
}
while( *buff == ' ' ) ++buff;
return( buff );
} /* StripSpaces */
/*
* ClassifyParm - decide if a parm is a pointer, word or dword
*/
parm_types ClassifyParm( char *buff )
{
buff = StripSpaces( buff );
if( IsWord( buff ) ) {
return( PARM_WORD );
} else if( strchr( buff, '*' ) != NULL ) {
return( PARM_PTR );
} else if( stricmp( buff, "void" ) == 0 ) {
return( PARM_VOID );
} else {
return( PARM_DWORD );
}
} /* ClassifyParm */
/*
* ClassifyReturnType - decide if type is a pointer, int, void, char, or dword
*/
return_types ClassifyReturnType( char *buff )
{
buff = StripSpaces( buff );
if( stricmp( buff, "int" ) == 0 || stricmp( buff, "short" ) == 0 ) {
return( RETURN_INT );
} else if( stricmp( buff, "void" ) == 0 ) {
return( RETURN_VOID );
} else if( stricmp( buff, "char" ) == 0 ) {
return( RETURN_CHAR );
} else if( strchr( buff, '*' ) != NULL ) {
return( RETURN_PTR );
} else {
return( RETURN_DWORD );
}
} /* ClassifyReturnType */
void ClassifyParmList( char *plist, fcn *tmpf )
{
int i;
int j;
int k;
int parmcnt;
struct parmlist *p;
struct subparm *subparm;
char parm_list[32];
char c;
char parmtype;
k = 0;
i = 0;
parmcnt = 0;
for(;;) {
c = plist[i];
if( c == '\0' || c == ',' ) {
plist[i] = '\0';
parmtype = ClassifyParm( &plist[k] );
if( parmtype == PARM_DOUBLE ) {
parmtype = PARM_DWORD;
parm_list[parmcnt++] = parmtype;
}
parm_list[parmcnt++] = parmtype;
if( c == '\0' ) break;
k = i + 1;
} else if( c == '[' ) {
plist[i] = '\0';
j = i + 1;
for(;;) {
i++;
c = plist[i];
if( c == ';' || c == ']' ) {
plist[i] = '\0';
subparm = myalloc( sizeof( struct subparm ) );
subparm->nextparm = tmpf->subparms;
tmpf->subparms = subparm;
subparm->parmnum = parmcnt;
subparm->offset = atoi( &plist[j] );
j = i + 1;
if( c == ']' ) break;
}
}
}
i++;
}
if( parmcnt == 1 && parm_list[0] == PARM_VOID ) {
tmpf->pcnt = 0;
tmpf->aliascnt = 0;
tmpf->plist = NULL;
} else {
p = ParmList;
for(;;) {
if( p == NULL ) break;
if( p->parm_count == parmcnt ) {
if( memcmp( p->parm_types, parm_list, parmcnt ) == 0 ) break;
}
p = p->next;
}
if( p == NULL ) {
p = myalloc( sizeof(struct parmlist) + parmcnt );
p->next = ParmList;
ParmList = p;
p->parm_count = parmcnt;
memcpy( p->parm_types, parm_list, parmcnt );
p->alias_count = 0;
for( i = 0; i < parmcnt; i++ ) {
if( parm_list[i] == PARM_PTR ) {
p->alias_count++;
}
}
if( p->alias_count > MaxAliasCount ) {
MaxAliasCount = p->alias_count;
}
}
tmpf->pcnt = parmcnt;
tmpf->aliascnt = p->alias_count;
tmpf->plist = p->parm_types;
}
} /* ClassifyParmList */
int main( int argc, char *argv[] )
{
char *name,*dir;
FILE *f,*pf;
char defname[80];
char fname[50];
int i,j;
_nheapgrow();
j=argc-1;
while( j > 0 ) {
if( argv[j][0] == '-' ) {
for(i=1;i<strlen(argv[j]);i++) {
switch( argv[j][i] ) {
case 'q': quiet = 1; break;
case 's': genstubs=1; break;
case '?':
printf("conv -s (gen stubs)\n");
exit(1);
default:
fprintf(stderr,"Unrecognized switch %c",argv[j][i] );
break;
}
}
for(i=j;i<argc;i++) {
argv[i]=argv[i+1];
}
argc--;
}
j--;
}
if( argc < 2 ) {
name = "win386";
} else {
name = argv[1];
}
if( argc < 3 ) {
dir = "def";
} else {
dir = argv[2];
}
pf = fopen( name,"r" );
if( pf == NULL ) {
printf("error opening file %s\n",name );
exit( 1 );
}
while( fgets( fname, 50, pf ) != NULL ) {
fname[ strlen( fname ) - 1 ] = 0;
#ifdef __UNIX__
sprintf( defname, "%s/%s", dir, fname );
#else
sprintf( defname, "%s\\%s", dir, fname );
#endif
f = fopen( defname, "r" );
if( f == NULL ) {
printf("error opening file %s\n", defname );
exit( 1 );
}
ProcessDefFile( f );
fclose( f );
}
fclose( pf );
BuildClasses();
GenerateCode();
GenerateThunkC();
GenerateCStubs();
ClosingComments();
return( 0 );
} /* main */
void ProcessDefFile( FILE *f )
{
char buff[MAX_BUFF];
int i,j,k;
char *fn; // function name
char *type; // return type
char *plist; // parameter list
fcn *tmpf;
while( fgets( buff, MAX_BUFF, f ) != NULL ) {
if( buff[0] == '#' ) {
continue;
}
if( buff[0] == '!' ) {
ThunkStrs = _fmyrealloc( ThunkStrs, sizeof( char *) *
(ThunkIndex + 1) );
i = strlen( buff );
ThunkStrs[ThunkIndex] = _fmyalloc( i-2 );
buff[i-1] = '\0';
_fstrcpy( ThunkStrs[ThunkIndex], &buff[1] );
ThunkIndex++;
continue;
}
/*
* flag a function that returns a pointer to a function
*/
if( strncmp( buff, "int (", 5 ) == 0 ) {
printf( "Oh, oh, something returns a function!!!\n" );
exit( 1 );
}
/*
* look for opening paren
*/
i = 0;
while( buff[i] != '(' ) {
i++;
}
/*
* look for closing ')'
*/
j = i;
k = 0; // keep track of nested ()
for(;;) {
if( buff[j] == ')' ) {
--k;
if( k == 0 ) break;
} else if( buff[j] == '(' ) {
++k;
}
++j;
}
/*
* back up away from opening paren to obtain function name
*/
k = i;
for(;;) {
if( buff[k] == ' ' ) break;
if( buff[k] == '*' ) break;
if( k == 0 ) break;
k--;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?