echoapi.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 704 行 · 第 1/2 页
C
704 行
/****************************************************************************
*
* 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: Echo CG API calls and track handle usage (for debugging).
*
****************************************************************************/
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "standard.h"
#include "coderep.h"
#include "cgdefs.h"
#include "typedef.h"
#include "spawn.h"
#include "tree.h"
#include "seldef.h"
#include "echoapi.h"
#include "model.h"
#include "sysmacro.h"
#include "useinfo.h"
#include "dump.h"
#include "feprotos.h"
extern void FatalError(char *);
extern type_def *TypeAddress(cg_type);
extern bool GetEnvVar(char*,char*,int);
extern int BGInlineDepth( void );
#define hdlSetUsed( handle, value ) ( ((use_info *)handle)->used = value )
#define hdlSetup( hdltype, handle ) ( handleSetup( hdltype, (use_info *)handle) )
#define hdlAddReuse( hdltype, handle ) ( handleAddReuse( hdltype, (use_info *)handle) )
// ERROR MESSAGE FUNCTIONS
static FILE *EchoAPIFile = NULL;
static int EchoAPIFlush = 0;
static void EchoAPIRedirect( void )
/*************************************/
{
char tmpfile[PATH_MAX];
if( GetEnvVar("echoapiflush", tmpfile, 11 ) ) {
EchoAPIFlush = 1;
}
if( GetEnvVar("echoapifile", tmpfile, 11 ) ) {
EchoAPIFile = fopen( tmpfile, "wt" );
}
}
static void EchoAPIUnredirect( void )
/***************************************/
{
if( EchoAPIFile == NULL ) return;
fclose( EchoAPIFile );
EchoAPIFile = NULL;
}
static void EchoAPIChar( char c )
/***********************************/
{
/* if the codegen is crashing we want flushing to occur
*/
if( EchoAPIFile != NULL ) {
fputc( c, EchoAPIFile );
if( EchoAPIFlush ) {
fflush( EchoAPIFile );
}
} else {
fputc( c, stdout );
if( EchoAPIFlush ) {
fflush( stdout );
}
}
}
static void EchoAPIString( char const *s )
/********************************************/
{
while( *s ) {
EchoAPIChar( *s );
s++;
}
}
static void errMsg // PRINT ERROR MESSAGE
( char const *msg ) // - message
{
DumpString( "\n**** CgDbg Failure: " );
DumpString( msg );
DumpChar( '\n' );
}
static void handleFailure( void )
{
DumpString( "Aborted after CgDbg Failure" );
EchoAPIUnredirect();
FatalError( "CGDbg Failure\n" );
}
static void printName( handle_type hdltype )
{
switch( hdltype ) {
case NO_HANDLE :
DumpString("uninitialized");
break;
case CG_NAMES :
DumpString("cg_name");
break;
case LABEL_HANDLE :
DumpString("label_handle");
break;
case PATCH_HANDLE :
DumpString("patch_handle");
break;
case SEL_HANDLE :
DumpString("sel_handle");
break;
default :
DumpString("default");
break;
}
}
static void handleMsg // PRINT ERROR FOR RING
( handle_type hdltype,
char const* msg ) // - message
{
errMsg( msg );
DumpString( "\n**** CgDbg Failure: for " );
printName( hdltype );
DumpChar('\n');
handleFailure();
}
static void ErrExpectFound( handle_type expect, handle_type found )
{
DumpString( "\n**** CgDbg Failure: " );
DumpString( "\n\texpecting type ");
printName(expect);
DumpChar( '\n' );
DumpString( "\n\tfound type ");
printName(found);
DumpChar( '\n' );
handleFailure();
}
// TYPE CHECKING FUNCTIONS
void verifyNotUserType // VERIFY NOT A USER-DEFINED TYPE
( cg_type type ) // - that type
{
type_def *alias;
// Check for aliased types
alias = TypeAddress( type );
if( alias ) {
type = alias->refno;
}
if( type >= T_FIRST_FREE ) {
errMsg( "cannot use user-defined type" );
handleFailure();
}
}
// PRINTING SUPPORT
#define case_str( a ) case a : EchoAPIString( #a ); break;
#define case_prt( a, b ) case a : EchoAPIString( #b ); break;
static void EchoAPIHandle // EchoAPI A HANDLE
( int handle // - handle
, char const *lab ) // - label for handle
{
char buffer[16];
EchoAPIString( lab );
EchoAPIChar( '[' );
itoa( handle, buffer, 16 );
EchoAPIString( buffer );
EchoAPIChar( ']' );
}
static void dumpLineHeader( void ) // let us know how deep inline we are
{
int depth;
depth = BGInlineDepth();
while( depth-- != 0 ) {
EchoAPIChar( '\t' );
}
}
// debug output
void EchoAPI // EchoAPI ROUTINE
( const char* text // - text
, ... ) // - operands
{
if( _IsModel( ECHO_API_CALLS ) ) {
char buffer[256];
va_list args;
va_start( args, text );
dumpLineHeader();
for( ; *text != 0; ++text ) {
if( *text == '%' ) {
++text;
switch( *text ) {
case 'B' : {
EchoAPIHandle( (int)va_arg( args, back_handle ), "bh" );
break;
}
case 'c' : {
char const * text = va_arg( args, char const * );
EchoAPIString( text );
break;
}
case 'C' : {
EchoAPIHandle( (int)va_arg( args, call_handle ), "ch" );
break;
}
case 'i' : {
int val = va_arg( args, int );
itoa( val, buffer, 10 );
EchoAPIString( buffer );
break;
}
case 'L' : {
EchoAPIHandle( (int)va_arg( args, label_handle ), "lh" );
break;
}
case 'o' : {
cg_op op = va_arg( args, cg_op );
switch( op ) {
case_str( O_NOP )
case_prt( O_PLUS, + )
case_str( O_INTERNAL_01 )
case_prt( O_MINUS, - )
case_str( O_INTERNAL_02 )
case_prt( O_TIMES, * )
case_str( O_INTERNAL_03 )
case_prt( O_DIV, / )
case_str( O_MOD )
case_prt( O_AND, & )
case_prt( O_OR, | )
case_prt( O_XOR, ^ )
case_prt( O_RSHIFT, >> )
case_prt( O_LSHIFT, << )
case_str( O_POW )
case_str( O_INTERNAL_16 )
case_str( O_ATAN2 )
case_str( O_FMOD )
case_str( O_UMINUS )
case_str( O_COMPLEMENT )
case_str( O_LOG )
case_str( O_COS )
case_str( O_SIN )
case_str( O_TAN )
case_str( O_SQRT )
case_str( O_FABS )
case_str( O_ACOS )
case_str( O_ASIN )
case_str( O_ATAN )
case_str( O_COSH )
case_str( O_EXP )
case_str( O_LOG10 )
case_str( O_SINH )
case_str( O_TANH )
case_str( O_PTR_TO_NATIVE )
case_str( O_PTR_TO_FOREIGN )
case_str( O_PARENTHESIS )
case_prt( O_CONVERT, <c= )
case_str( O_ROUND )
case_str( O_GETS )
case_str( O_INTERNAL_05 )
case_str( O_INTERNAL_06 )
case_str( O_INTERNAL_07 )
case_str( O_INTERNAL_08 )
case_str( O_INTERNAL_09 )
case_str( O_INTERNAL_10 )
case_str( O_INTERNAL_11 )
case_str( O_INTERNAL_14 )
case_str( O_INTERNAL_15 )
case_prt( O_EQ, == )
case_prt( O_NE, != )
case_prt( O_GT, > )
case_prt( O_LE, <= )
case_prt( O_LT, < )
case_prt( O_GE, >= )
case_str( O_INTERNAL_12 )
case_str( O_INTERNAL_17 )
case_str( O_INTERNAL_18 )
case_str( O_INTERNAL_19 )
case_str( O_INTERNAL_20 )
case_str( O_INTERNAL_21 )
case_str( O_INTERNAL_22 )
case_str( O_INTERNAL_23 )
case_str( O_INTERNAL_24 )
case_str( O_INTERNAL_25 )
case_str( O_INTERNAL_26 )
case_str( O_INTERNAL_27 )
case_str( O_INTERNAL_28 )
case_str( O_INTERNAL_29 )
case_str( O_INTERNAL_30 )
case_str( O_INTERNAL_31 )
case_str( O_INTERNAL_32 )
case_str( O_INTERNAL_33 )
case_str( O_INTERNAL_34 )
case_str( O_STACK_ALLOC )
case_str( O_VA_START )
case_str( O_SLACK_31 )
case_str( O_SLACK_32 )
case_str( O_SLACK_33 )
case_str( O_SLACK_34 )
case_str( O_SLACK_35 )
case_str( O_SLACK_36 )
case_str( O_SLACK_37 )
case_str( O_SLACK_38 )
case_str( O_SLACK_39 )
case_str( O_INTERNAL_13 )
case_prt( O_FLOW_AND, && )
case_prt( O_FLOW_OR, || )
case_str( O_FLOW_OUT )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?