📄 token.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include "langext.h"
#include "defines.h"
#include "types.h"
#include "subs.h"
#include "globals.h"
/* TOKEN.C */
/*+-------------------------------------------------------------------------+
| |
| complete_a_filename_token |
| |
+-------------------------------------------------------------------------+*/
void complete_a_filename_token()
BeginDeclarations
EndDeclarations
BeginCode
copy_string(token, next_token);
scan_out_token();
loop:
If token_type Is switch_end_token_type
Then
concat_string(token, next_token);
scan_out_token();
If token_type Is filename_token_type
Then
concat_string(token, next_token);
scan_out_token();
EndIf;
Else While token_type Is indirect_file_token_type
BeginWhile
concat_char_to_string(token, '@');
scan_out_token();
goto loop;
EndWhile;
EndIf;
return;
EndCode
/*+-------------------------------------------------------------------------+
| |
| eat_white_space |
| |
+-------------------------------------------------------------------------+*/
void eat_white_space()
BeginDeclarations
EndDeclarations
BeginCode
While token_break_char Is ' '
BeginWhile
token_get_char();
EndWhile;
EndCode
/*+-------------------------------------------------------------------------+
| |
| get_free_token_source_element |
| |
+-------------------------------------------------------------------------+*/
token_stack_ptr get_free_token_source_element()
BeginDeclarations
token_stack_ptr elem;
EndDeclarations
BeginCode
Pop token_stack_free_list InTo elem EndPop;
If elem IsNull
Then
elem = (token_stack_ptr)
allocate_memory(Bit_32(sizeof(token_stack_type)));
EndIf;
return(elem);
EndCode
/*+-------------------------------------------------------------------------+
| |
| get_filename_token |
| |
+-------------------------------------------------------------------------+*/
void get_filename_token(bit_16 required,
file_info_list *list)
BeginDeclarations
#define List (*list)
token_stack_ptr source_element;
#define Source_element (*source_element)
EndDeclarations
BeginCode
Loop
BeginLoop
required = (required) AndIf (List.first IsNull);
If token_type Is text_token_type
Then
linker_error(8, "Input syntax error: \"%s\" out of place.\n",
String(next_token));
EndIf;
If token_type Is indirect_file_token_type
Then
scan_out_token();
If token_type IsNot filename_token_type
Then
linker_error(8,"Input syntax error: Expected filename after '@'.\n");
EndIf;
complete_a_filename_token();
source_element = get_free_token_source_element();
Source_element.break_char = token_break_char;
Source_element.source_file = input_open(token);
Source_element.token_string = Null;
Source_element.token_string_index = 0;
Push source_element OnTo token_stack EndPush;
token_break_char = ' ';
scan_out_token();
ContinueLoop;
EndIf;
If token_type Is switch_token_type
Then
process_switch();
ContinueLoop;
EndIf;
If token_type Is continuation_token_type
Then
scan_out_token();
If token_type Is line_end_token_type
Then
scan_out_token();
EndIf;
ContinueLoop;
EndIf;
If token_type Is filename_token_type
Then
complete_a_filename_token();
more_tokens = True;
return;
EndIf;
If ((token_type Is end_of_command_line_token_type) AndIf
(List.first IsNull)) OrIf
((required) AndIf
((token_type Is separator_token_type) OrIf
(token_type Is line_end_token_type)))
Then
If (*token_stack.first).source_file IsNot stdin
Then
source_element = get_free_token_source_element();
Source_element.source_file = stdin;
Source_element.token_string = Null;
Source_element.token_string_index = 0;
Push source_element OnTo token_stack EndPush;
token_break_char = ' ';
EndIf;
If default_prompt IsNotNull
Then
linker_message(default_prompt, String(default_filename));
prompt_next_stdin = False;
default_prompt = Null;
EndIf;
scan_out_token();
ContinueLoop;
EndIf;
If List.first IsNull
Then
If (token_type Is separator_token_type) OrIf
(token_type Is terminator_token_type)
Then
If prompting_for Is 2
Then
If comfile.val IsTrue
Then
default_extension = com_extension_string;
Else
If sysfile.val IsTrue
Then
default_extension = sys_extension_string;
Else
If build_DLL.val IsTrue
Then
default_extension = dll_extension_string;
Else
default_extension = exe_extension_string;
EndIf ;
EndIf;
EndIf;
change_extension(default_filename, default_extension);
EndIf;
copy_string(token, default_filename);
more_tokens = False;
return;
EndIf;
Else
If (token_type Is separator_token_type) OrIf
(token_type Is terminator_token_type) OrIf
(token_type Is end_of_command_line_token_type)
Then
copy_string(token, null_string);
more_tokens = False;
return;
EndIf;
EndIf;
If token_type Is line_end_token_type
Then
If List.first IsNull
Then
If prompting_for Is 2
Then
If comfile.val IsTrue
Then
default_extension = com_extension_string;
Else
If sysfile.val IsTrue
Then
default_extension = sys_extension_string;
Else
If build_DLL.val IsTrue
Then
default_extension = dll_extension_string;
Else
default_extension = exe_extension_string;
EndIf ;
EndIf;
EndIf;
change_extension(default_filename, default_extension);
EndIf;
copy_string(token, default_filename);
Else
copy_string(token, null_string);
EndIf;
If (*token_stack.first).source_file Is stdin
Then
Pop token_stack InTo source_element EndPop;
Push source_element OnTo token_stack_free_list EndPush;
EndIf;
prompt_next_stdin = False;
more_tokens = False;
return;
EndIf;
EndLoop;
return;
EndCode
#undef List
#undef Source_element
/*+-------------------------------------------------------------------------+
| |
| input_open |
| |
+-------------------------------------------------------------------------+*/
FILE *input_open(string_ptr fn)
BeginDeclarations
FILE *infile;
EndDeclarations
BeginCode
infile = fopen((char *)near_string(fn), "r");
If infile Is NULL
Then
linker_error(8, "Could not open file \"%s\" for input.\n",
String(fn));
EndIf;
return(infile);
EndCode
/*+-------------------------------------------------------------------------+
| |
| process_switch |
| |
+-------------------------------------------------------------------------+*/
void process_switch()
BeginDeclarations
switch_table_ptr current_switch;
#define Current_switch (*current_switch)
EndDeclarations
BeginCode
current_switch = switch_table;
scan_out_token();
copy_string(token, next_token);
lowercase_string(token);
While Current_switch.full_name IsNotNull
BeginWhile
If compare_string(token, string((byte *)Current_switch.abbr_name)) IsZero
Then
Current_switch.switch_processor(current_switch);
return;
EndIf;
If (Length(token) NotLessThan Current_switch.min_length) AndIf
(far_compare(String(token), (byte *) Current_switch.full_name,
Length(token)) IsZero)
Then
Current_switch.switch_processor(current_switch);
return;
EndIf;
current_switch++;
EndWhile;
linker_error(8,"Syntax error: \"%s\" is an unknown switch.\n",
String(token));
return;
EndCode
#undef Current_switch
/*+-------------------------------------------------------------------------+
| |
| scan_bit_32_switch |
| |
+-------------------------------------------------------------------------+*/
void scan_bit_32_switch(switch_table_ptr current_switch)
BeginDeclarations
#define Current_switch (*current_switch)
#define Affected_thing (*((bit_32_switch_ptr)(*current_switch).affected_thing))
EndDeclarations
BeginCode
scan_out_token();
copy_string(token, next_token);
If token_type IsNot switch_end_token_type
Then
linker_error(8,"Syntax error: \":\" did not follow switch \"%s\"\n",
Current_switch.full_name);
EndIf;
scan_out_token();
copy_string(token, next_token);
If (Not token_is_number) OrIf
(token_numeric_value LessThan Affected_thing.min) OrIf
(token_numeric_value GreaterThan Affected_thing.max)
Then
linker_error(8,"Syntax error: Switch \"%s\" requires a numeric value\n"
" between %u and %u\n",
Current_switch.full_name,
Affected_thing.min, Affected_thing.max);
Else
Affected_thing.val = token_numeric_value;
Affected_thing.set = True;
EndIf;
scan_out_token();
copy_string(token, next_token);
return;
EndCode
#undef Current_switch
#undef Affected_thing
/*+-------------------------------------------------------------------------+
| |
| scan_bit_32_align_switch |
| |
+-------------------------------------------------------------------------+*/
void scan_bit_32_align_switch(switch_table_ptr current_switch)
BeginDeclarations
#define Current_switch (*current_switch)
#define Affected_thing (*((bit_32_switch_ptr)(*current_switch).affected_thing))
bit_32 val,i = 0,v = 0 ;
EndDeclarations
BeginCode
scan_bit_32_switch(current_switch) ;
val = Affected_thing.val ;
While val GreaterThan 1
BeginWhile
If val And 1
Then
v = 1;
EndIf ;
val = val ShiftedRight 1 ;
i++ ;
EndWhile ;
Affected_thing.val = 1 << (i+ v) ;
EndCode
#undef Current_switch
#undef Affected_thing
/*+-------------------------------------------------------------------------+
| |
| scan_opt_bit_16 |
| |
+-------------------------------------------------------------------------+*/
void scan_opt_bit_16(switch_table_ptr current_switch)
BeginDeclarations
#define Current_switch (*current_switch)
#define Affected_thing (*((bit_32_switch_ptr)(*current_switch).affected_thing))
EndDeclarations
BeginCode
scan_out_token();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -