aliasgen.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 557 行 · 第 1/2 页
C
557 行
/****************************************************************************
*
* 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: Assembly alias stubs generation utility.
*
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#ifndef _MAX_PATH
#define _MAX_PATH PATH_MAX
#endif
struct SysElem {
char * system;
struct SysElem * next;
};
struct Alias {
char * filename;
char * realname;
char * aliasname;
struct SysElem * systems;
};
/*
* Automagically pass line number and file name to InternalError.
*/
#define Zoinks() InternalError( __LINE__, __FILE__ )
/*
* If format==NULL, a default error message is displayed using perror().
* Otherwise, format is treated as the format string, and passed to
* vfprintf() with any arguments specified after it. This function
* terminates the program, returning exit status EXIT_FAILURE.
*/
void FatalError( char *format, ... )
/**********************************/
{
va_list args;
if( format == NULL ) {
perror( "Fatal error" );
} else {
va_start( args, format );
fprintf( stderr, "Fatal error: " );
vfprintf( stderr, format, args );
fprintf( stderr, "\n" );
va_end( args );
}
exit( EXIT_FAILURE );
}
/*
* Point out the offending location and exit with status EXIT_FAILURE.
*/
void InternalError( int line, char *file )
/****************************************/
{
fprintf( stderr, "Internal error on line %d of %s; please contact Watcom\n",
line, file );
exit( EXIT_FAILURE );
}
/*
* Print a warning message.
*/
void Warning( char *format, ... )
/*******************************/
{
va_list args;
va_start( args, format );
fprintf( stderr, "Warning: " );
vfprintf( stderr, format, args );
fprintf( stderr, "\n" );
va_end( args );
}
/*
* Allocate a block of memory, aborting program execution with an error
* message if there is insufficient memory.
*/
void *AllocMem( size_t bytes )
/****************************/
{
void * p;
p = malloc( bytes );
if( p == NULL ) FatalError( "Insufficient memory." );
return( p );
}
/*
* Reallocate a block of memory, aborting program execution with an error
* message if there is insufficient memory.
*/
void *ReallocMem( void *buf, size_t bytes )
/*****************************************/
{
void * p;
p = realloc( buf, bytes );
if( p == NULL ) FatalError( "Insufficient memory." );
return( p );
}
/*
* Free a block of memory.
*/
void FreeMem( void *buf )
/***********************/
{
free( buf );
}
/*
* Duplicate a string.
*/
char *DupStrMem( char *str )
/**************************/
{
char * p;
p = AllocMem( strlen( str ) + 1 );
strcpy( p, str );
return( p );
}
/*
* Returns the number of whitespace-delimited words in 'command'. If 'words'
* is non-NULL, then each word will have memory allocated to hold it and will
* be copied into the appropriate space in the array (e.g. the second word
* will be copied into words[1]). The array must be large enough, so just
* call parse_words with 'words'==NULL before to get the proper size, then
* do an alloca((n+1)*sizeof(char*)). The caller is responsible for freeing
* any memory allocated for the words. Returns -1 on error.
*/
static int parse_words( const char *command, char **words )
/*********************************************************/
{
int numWords = 0;
const char * p = command;
const char * pLookAhead;
size_t len;
while( *p != '\0' ) {
/*** Skip any leading whitespace ***/
while( isspace( *p ) ) p++;
/*** Handle the word ***/
if( *p == '\0' ) break;
pLookAhead = p;
while( *pLookAhead != '\0' && !isspace( *pLookAhead ) ) {
pLookAhead++;
}
if( words != NULL ) {
len = pLookAhead - p; /* # of chars, excluding the null */
words[numWords] = (char *)AllocMem( (len+1) * sizeof(char) );
strncpy( words[numWords], p, len );
words[numWords][len] = '\0';
}
p = pLookAhead;
numWords++;
}
if( words != NULL ) words[numWords] = NULL; /* last string */
return( numWords );
}
/*
* Add a system name to an Alias' system list.
*/
static void add_system( struct Alias *alias, char *system )
/*********************************************************/
{
struct SysElem * syselem;
syselem = (struct SysElem*)AllocMem( sizeof( struct SysElem ) );
syselem->system = system;
syselem->next = alias->systems;
alias->systems = syselem;
}
/*
* Add a line to the MIF file.
*/
static void update_mif_file( FILE *miffile, char *obj, struct Alias *alias )
/**************************************************************************/
{
struct SysElem * syselem;
fprintf( miffile, "!inject %s", obj );
syselem = alias->systems;
while( syselem != NULL ) {
fprintf( miffile, " %s", syselem->system );
syselem = syselem->next;
}
fprintf( miffile, "\n" );
if( ferror( miffile ) ) {
FatalError( "Cannot write to MIF file." );
}
}
/*
* Make an AXP assembler file defining the alias.
*/
static void make_asm_axp( FILE *miffile, struct Alias *alias, char *outdir )
/**************************************************************************/
{
char filename[_MAX_PATH];
FILE * asmfile;
/*** Open the assembler file ***/
sprintf( filename, "%s_a%6s.asm", outdir, alias->filename );
asmfile = fopen( filename, "wt" );
if( asmfile == NULL ) {
FatalError( "Cannot create '%s'.", filename );
}
/*** Write data to it ***/
fprintf( asmfile, "\t.text\n" );
fprintf( asmfile, "\t.globl\t%s\n", alias->aliasname );
fprintf( asmfile, "%s:\n", alias->aliasname );
fprintf( asmfile, "\tbr\t%s\n", alias->realname );
if( ferror( asmfile ) ) {
FatalError( "Cannot write to '%s'.", filename );
}
fclose( asmfile );
sprintf( filename, "_a%6s.obj", alias->filename );
update_mif_file( miffile, filename, alias );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?