📄 cdump.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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "cvars.h"
extern char *Tokens[];
/* matches table of type in ctypes.h */
static char *CTypeNames[] = {
"signed char",
"unsigned char",
"short",
"unsigned short",
"int",
"unsigned int",
"long",
"unsigned long",
"__int64",
"unsigned __int64",
"float",
"double",
"pointer",
"array",
"struct",
"union",
"function",
"field",
"void",
"enum",
"<typdef>",
"<ufield>",
"...",
"<char>",
"<wide char>",
"long double",
"float _Complex",
"double _Complex",
"long double _Complex",
"float _Imaginary",
"double _Imaginary",
"long double _Imaginary",
"_Bool",
};
static char do_message_output; /* Optimize output for human */
typedef struct
{
char *data;
size_t cursize;
size_t maxsize;
} STRCHUNK;
#define STRCHUNK_INCREMENT 512
static void ChunkInit(STRCHUNK *pch)
{
pch->data = NULL;
pch->cursize = 0;
pch->maxsize = 0;
}
static char *ChunkToStr(STRCHUNK *pch)
{
char *ret;
ret = pch->data;
if( ret == NULL ) {
ret = CStrSave( "" );
}
return ret;
}
static void ChunkSaveData( STRCHUNK *pch, const char *data, size_t len )
{
int bytesleft;
int requestbytes;
char *newdata;
bytesleft = pch->maxsize - (pch->cursize+len+1);
if( bytesleft <= 0 ) {
requestbytes = -bytesleft;
if( requestbytes < STRCHUNK_INCREMENT ) {
requestbytes = STRCHUNK_INCREMENT;
}
requestbytes += pch->maxsize;
newdata = CMemAlloc( requestbytes );
if( pch->data ) {
memcpy( newdata, pch->data, pch->cursize );
CMemFree( pch->data );
}
pch->data = newdata;
pch->maxsize = requestbytes;
}
memcpy( pch->data+pch->cursize, data, len );
pch->cursize += len;
pch->data[pch->cursize] = '\0';
}
static void ChunkSaveStr( STRCHUNK *pch, const char *str )
{
ChunkSaveData( pch, str, strlen( str ) );
}
static void ChunkSaveChar( STRCHUNK *pch, char ch )
{
ChunkSaveData( pch, &ch, 1 );
}
static void ChunkSaveStrWord( STRCHUNK *pch, const char *str )
{
ChunkSaveStr( pch, str );
ChunkSaveChar( pch, ' ' );
}
#ifdef FDEBUG
void DumpToken()
{
int value;
if( DebugFlag >= 3 ) {
printf( "%2d: ", CurToken );
if( CurToken == T_ID )
printf( "%s\n", Buffer );
else if( CurToken == T_STRING )
printf( "\"%s\"\n", Buffer );
else if( CurToken == T_CONSTANT ) {
value = Constant;
printf( "%d\n", value );
} else
printf( "'%s'\n", Tokens[ CurToken ] );
}
}
#endif
#if 0
void DumpTypeCounts()
{
int i;
for( i = TYPE_CHAR; i <= TYPE_VOID; ++i ) {
printf( "%3d %s\n", CTypeCounts[i], CTypeNames[i] );
}
printf( "%d pointer nodes\n", CTypeCounts[TYPE_POINTER] );
}
#endif
static TYPEPTR TrueType( TYPEPTR typ )
{
TYPEPTR newtyp;
if ( typ == NULL )
return typ;
if ( do_message_output ) {
/* For human: smart typedef expansion. Stop before unnamed struct */
while ( typ->decl_type == TYPE_TYPEDEF ) {
newtyp = typ->object;
if( newtyp->decl_type == TYPE_STRUCT ||
newtyp->decl_type == TYPE_UNION ||
newtyp->decl_type == TYPE_ENUM ) {
if ( *newtyp->u.tag->name == '\0' )
break;
}
typ = newtyp;
}
} else {
if( !CompFlags.dump_prototypes) {
/* -zg, not -v */
while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
}
}
return( typ );
}
static TYPEPTR Object( TYPEPTR typ )
{
return( TrueType( typ->object ) );
}
static void DumpPointer( TYPEPTR typ, STRCHUNK *pch ) ;
static void DumpTail( TYPEPTR typ, SYMPTR funcsym, int pointer_flags, STRCHUNK *pch );
static void DumpDecl( TYPEPTR typ, SYMPTR funcsym, STRCHUNK *pch );
static void put_keyword( int keyword, STRCHUNK *pch );
static void DumpFlags( int flags, TYPEPTR typ, STRCHUNK *fp );
static void DumpBaseType( TYPEPTR typ, STRCHUNK *pch );
static void DumpArray( TYPEPTR typ, STRCHUNK *pch );
static void DumpParmTags( TYPEPTR *parm, FILE *fp );
static void DumpTagName( char *tag_name, STRCHUNK *pch );
static TYPEPTR DefArgPromotion( TYPEPTR arg_typ );
static void DumpParmList( TYPEPTR *parm, SYMPTR funcsym, STRCHUNK *pch );
void DumpFuncDefn(void)
{
TYPEPTR typ;
FNAMEPTR flist;
STRCHUNK chunk;
char *result;
typ = CurFunc->sym_type;
DumpParmTags( typ->u.parms, DefFile );
flist = FileIndexToFName( CurFunc->defn_file_index );
fprintf( DefFile, "//#line \"%s\" %u\n", /* 07-jun-94 */
flist->name,
CurFunc->d.defn_line );
ChunkInit( &chunk );
if( CurFunc->stg_class == SC_STATIC ) {
put_keyword( T_STATIC, &chunk );
} else {
put_keyword( T_EXTERN, &chunk );
}
if( CurFunc->flags & SYM_TYPE_GIVEN ) {
DumpBaseType( Object( typ ), &chunk );
}
DumpDecl( typ, CurFunc, &chunk );
result = ChunkToStr( &chunk );
fprintf( DefFile, "%s;\n", result );
CMemFree( result );
}
static void DumpPointer( TYPEPTR typ, STRCHUNK *pch ) /* 26-may-89 */
{
if( typ->decl_type == TYPE_POINTER ) {
DumpPointer( Object( typ ), pch );
if( !( typ->u.p.decl_flags & FLAG_WAS_ARRAY) ) { /* 07-jun-94 */
DumpFlags( typ->u.p.decl_flags & ~(FLAG_CONST|FLAG_VOLATILE),
typ, pch );
DumpFlags( typ->u.p.decl_flags & (FLAG_CONST|FLAG_VOLATILE),
typ, pch );
ChunkSaveChar( pch, '*' );
}
}
}
static void DumpTail( TYPEPTR typ, SYMPTR funcsym, int pointer_flags, STRCHUNK *pch )
{
TYPEPTR top_typ;
TYPEPTR obj;
top_typ = typ;
for(;;) {
if( typ->decl_type == TYPE_FUNCTION ) {
ChunkSaveChar( pch, '(' );
if( typ == top_typ || typ->u.parms != NULL ) {
DumpParmList( typ->u.parms, funcsym, pch);
funcsym = NULL;
}
ChunkSaveChar( pch, ')' );
}
typ = Object( typ );
while( typ->decl_type == TYPE_POINTER ) {
typ = Object( typ );
}
if( typ->decl_type == TYPE_ARRAY ) {
ChunkSaveChar( pch, ')' );
if( pointer_flags & FLAG_WAS_ARRAY ) { /* 07-jun-94 */
/* we don't know the dimension anymore. just put out [1] */
ChunkSaveStr( pch, "[1]" );
pointer_flags = 0;
}
DumpArray( typ, pch) ;
for( ;; ) {
obj = Object( typ );
if( obj->decl_type != TYPE_ARRAY ) break;
typ = obj;
}
} else {
if( typ->decl_type != TYPE_FUNCTION ) break;
ChunkSaveChar( pch, ')' );
}
}
}
static void DumpDecl( TYPEPTR typ, SYMPTR funcsym, STRCHUNK *pch )
{
TYPEPTR obj;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -