asmline.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 738 行 · 第 1/2 页
C
738 行
/****************************************************************************
*
* 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: processing input line data and line queueing for macros
*
****************************************************************************/
#include "asmglob.h"
#include <ctype.h>
#include "asmins.h"
#include "asmdefs.h"
#if defined( _STANDALONE_ )
#include "directiv.h"
#include "asmalloc.h"
#include "condasm.h"
#include "asmexpnd.h"
#include "macro.h"
#include "asminput.h"
extern int in_prologue;
typedef struct line_list {
struct line_list *next;
char *line;
} line_list;
/* NOTE: the line queue is now a STACK of line queues
* when a macro is being expanded, we push a new line queue on the stack
* thus there is 1 queue on the stack for every level of nesting in macros
*/
typedef struct input_queue {
struct line_list *head;
struct line_list *tail;
struct input_queue *next;
} input_queue;
typedef struct file_list {
struct file_list *next;
union {
FILE *file;
struct input_queue *lines;
};
const FNAME *srcfile; /* name of include file */
unsigned long line_num; /* current line in parent file */
char is_a_file;
bool hidden;
} file_list;
extern void heap( char * );
extern char write_to_file;
extern uint_8 CheckSeg;
extern int_8 DefineProc; // TRUE if the definition of procedure
// has not ended
extern unsigned long PassTotal;
uint_32 BufSize; // size of CodeBuffer
static input_queue *line_queue = NULL; // line queue
static file_list *file_stack = NULL; // top of included file stack
static char *IncludePath = NULL;
#if defined(__UNIX__)
#define INCLUDE_PATH_DELIM ":"
#define DIR_SEPARATOR '/'
#define DIR_SEP_STRING "/"
#else
#define INCLUDE_PATH_DELIM ";"
#define DIR_SEPARATOR '\\'
#define DIR_SEP_STRING "\\"
#endif
#else
uint_32 AsmCodeAddress; // program counter
#endif
int Token_Count; // number of tokens on line
unsigned char *AsmCodeBuffer; // code buffer for generated bytes
#if defined( _STANDALONE_ )
static bool get_asmline( char *ptr, unsigned max, FILE *fp )
/**********************************************************/
{
char quote = 0;
bool skip;
int c;
int got_something;
/* blow away any comments -- look for ;'s */
/* note that ;'s are ok in quoted strings */
skip = FALSE;
got_something = FALSE;
for( ;; ) {
c = getc( fp );
/* copy the line until we hit a NULL, newline, or ; not in a quote */
switch( c ) {
case '\'':
case '"':
case '`':
if( quote == 0 ) {
quote = c;
} else if( c == quote ) {
quote = 0;
}
break;
case '<':
if( quote == 0 ) {
quote = '>';
}
break;
case '>':
if( c == quote ) {
quote = 0;
}
break;
case ';':
if( quote != 0 ) {
break;
}
skip = TRUE;
break;
case '\n':
/* if continuation character found, pass over newline */
if( (got_something == TRUE) && (*(ptr - 1) == '\\') ) {
ptr--;
max++;
LineNumber++;
continue; /* don't store character in string */
}
*ptr = '\0';
// fall through
case '\0':
/* we have found the end of the line */
return( TRUE );
case EOF:
*ptr = '\0';
return( got_something );
}
if( !skip ) {
*ptr++ = c;
if( --max <= 1 )
skip = TRUE;
got_something = TRUE;
}
}
}
void PushLineQueue( void )
/************************/
{
input_queue *new;
DebugMsg(( "PUSHLINEQUEUE\n" ));
new = AsmAlloc( sizeof( input_queue ) );
new->next = line_queue;
new->head = new->tail = NULL;
line_queue = new;
}
bool PopLineQueue( void )
/***********************/
/* remove a line queue from the top of the stack & throw it away */
{
input_queue *tmp;
/* pop the line_queue stack */
tmp = line_queue;
in_prologue = FALSE;
if( tmp == NULL )
return( FALSE );
line_queue = line_queue->next;
AsmFree( tmp );
return( TRUE );
}
bool GetQueueMacroHidden( void )
/******************************/
{
if(( file_stack != NULL ) && !file_stack->is_a_file ) {
return( file_stack->hidden );
} else {
return( FALSE );
}
}
static line_list *enqueue( void )
/*******************************/
{
line_list *new;
new = AsmAlloc( sizeof( line_list ) );
new->next = NULL;
if( line_queue == NULL ) {
line_queue = AsmAlloc( sizeof( input_queue ) );
line_queue->next = NULL;
line_queue->tail = NULL;
line_queue->head = NULL;
}
if( line_queue->tail == NULL ) {
line_queue->head = new;
line_queue->tail = new;
} else {
/* insert at the tail */
line_queue->tail->next = new;
line_queue->tail = new;
}
return( new );
}
static file_list *push_flist( const char *name, bool is_a_file )
/**************************************************************/
{
file_list *new;
new = AsmAlloc( sizeof( file_list ) );
new->next = file_stack;
file_stack = new;
new->line_num = LineNumber;
new->is_a_file = is_a_file;
new->hidden = 0;
if( !is_a_file ) {
dir_node *dir;
dir = (dir_node *)AsmGetSymbol( name );
LineNumber = dir->line_num;
new->srcfile = dir->e.macroinfo->srcfile;
} else {
new->srcfile = AddFlist( name );
LineNumber = 0;
}
return( new );
}
const FNAME *get_curr_srcfile( void )
/************************************/
{
return( file_stack == NULL ? ModuleInfo.srcfile : file_stack->srcfile );
}
void print_include_file_nesting_structure( void )
/***********************************************/
{
file_list *tmp;
unsigned tab = 1;
tmp = file_stack;
if( tmp == NULL )
return;
for( ; tmp != NULL ; ) {
if( tmp->next == NULL )
break;
if( !tmp->hidden ) {
if( tmp->is_a_file ) {
AsmNote( NOTE_INCLUDED_BY, tmp->next->srcfile->name, tmp->line_num );
} else {
AsmNote( NOTE_MACRO_CALLED_FROM, tmp->next->srcfile->name, tmp->line_num );
}
}
tmp = tmp->next;
tab++;
}
if( !tmp->hidden ) {
if( tmp->is_a_file ) {
AsmNote( NOTE_INCLUDED_BY, ModuleInfo.srcfile->name, tmp->line_num );
} else {
AsmNote( NOTE_MACRO_CALLED_FROM, ModuleInfo.srcfile->name, tmp->line_num );
}
}
}
void InputQueueLine( char *line )
/*******************************/
{
line_list *new;
DebugMsg(( "QUEUELINE: %s ( line %lu ) \n", line, LineNumber ));
new = enqueue();
new->line = AsmAlloc( strlen( line ) + 1 );
strcpy( new->line, line );
}
static FILE *open_file_in_include_path( char *name, char *fullpath )
/******************************************************************/
{
char *inc_path_list;
char *next_path;
char buffer[MAX_LINE_LEN];
FILE *file = NULL;
while( isspace( *name ) )
name++;
inc_path_list = AsmTmpAlloc( strlen( IncludePath ) + 1 );
strcpy( inc_path_list, IncludePath );
next_path = strtok( inc_path_list, INCLUDE_PATH_DELIM ";");
while( ( file == NULL ) && ( next_path != NULL ) ) {
strcpy( buffer, next_path );
//NYI: this is no good for DOS - have to check '/', '\\', and ':'
if( buffer[ strlen( buffer ) - 1] != DIR_SEPARATOR ) {
strcat( buffer, DIR_SEP_STRING );
}
strcat( buffer, name );
file = fopen( buffer, "r" );
if( file )
break;
next_path = strtok( NULL, INCLUDE_PATH_DELIM ";");
}
strcpy( fullpath, buffer );
return( file );
}
int InputQueueFile( char *path )
/******************************/
{
FILE *file;
file_list *new;
char fullpath[ _MAX_PATH ];
char *drive, *dir, *fname, *ext;
char buffer[ _MAX_PATH2 ];
char *tmp;
_splitpath2( path, buffer, &drive, &dir, &fname, &ext );
_makepath( fullpath, drive, dir, fname, ext );
file = fopen( fullpath, "r" );
tmp = path;
if( file == NULL && IncludePath != NULL ) {
tmp = buffer;
file = open_file_in_include_path( path, tmp );
}
if( file == NULL ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?