home *** CD-ROM | disk | FTP | other *** search
- /* TOKEN.C */
-
- /*+-------------------------------------------------------------------------+
- | |
- | complete_a_filename_token |
- | |
- +-------------------------------------------------------------------------+*/
- void complete_a_filename_token()
- BeginDeclarations
- EndDeclarations
- BeginCode
- copy_string(token, next_token);
- scan_out_token();
- 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;
- 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(Addr(static_pool),
- 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: \"%Fs\" 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
- default_extension = exe_extension_string;
- 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
- default_extension = exe_extension_string;
- 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 \"%Fs\" 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: \"%Fs\" is an unknown switch.\n",
- String(token));
- return;
- EndCode
- #undef Current_switch
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_bit_16_switch |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_bit_16_switch(switch_table_ptr current_switch)
- BeginDeclarations
- #define Current_switch (*current_switch)
- #define Affected_thing (*((bit_16_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_opt_bit_16 |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_opt_bit_16(switch_table_ptr current_switch)
- BeginDeclarations
- #define Current_switch (*current_switch)
- #define Affected_thing (*((bit_16_switch_ptr)(*current_switch).affected_thing))
- EndDeclarations
- BeginCode
- scan_out_token();
- copy_string(token, next_token);
- Affected_thing.set = True;
- If token_type IsNot switch_end_token_type
- Then
- Affected_thing.val = Affected_thing.def;
- return;
- 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;
- EndIf;
- scan_out_token();
- copy_string(token, next_token);
- return;
- EndCode
- #undef Current_switch
- #undef Affected_thing
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_out_token |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_out_token()
- BeginDeclarations
- bit_16 paren_count;
- EndDeclarations
- BeginCode
- eat_white_space();
- copy_string(next_token, null_string);
- token_is_hex_number =
- token_is_number = False;
- Using token_break_char
- BeginCase
- When '\n':
- prompt_next_stdin = True;
- concat_char_to_string(next_token, token_break_char);
- If token_stack.first Is token_stack.last
- Then
- token_type = end_of_command_line_token_type;
- Else
- token_type = line_end_token_type;
- EndIf;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When ',':
- concat_char_to_string(next_token, token_break_char);
- token_type = separator_token_type;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When ';':
- concat_char_to_string(next_token, token_break_char);
- token_type = terminator_token_type;
- break;
- When '+':
- concat_char_to_string(next_token, token_break_char);
- token_type = continuation_token_type;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When '/':
- concat_char_to_string(next_token, token_break_char);
- token_type = switch_token_type;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When ':':
- concat_char_to_string(next_token, token_break_char);
- token_type = switch_end_token_type;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When '@':
- concat_char_to_string(next_token, token_break_char);
- token_type = indirect_file_token_type;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- When '(':
- paren_count = 1;
- token_type = text_token_type;
- concat_char_to_string(next_token, token_break_char);
- While paren_count IsNotZero
- BeginWhile
- token_get_char();
- If token_break_char IsNot '\n'
- Then
- concat_char_to_string(next_token, token_break_char);
- Else
- If (*token_stack.first).source_file Is stdin
- Then
- linker_message("continue parenthesized text: ");
- EndIf;
- EndIf;
- If token_break_char Is '('
- Then
- paren_count++;
- EndIf;
- If token_break_char Is ')'
- Then
- paren_count--;
- EndIf;
- EndWhile;
- token_break_char = ' '; /* Make it look like we advanced a character */
- break;
- Otherwise:
- token_is_number = True;
- token_numeric_value = 0;
- While (token_break_char IsNot ',') AndIf
- (token_break_char IsNot ';') AndIf
- (token_break_char IsNot '+') AndIf
- (token_break_char IsNot '/') AndIf
- (token_break_char IsNot '@') AndIf
- (token_break_char IsNot ':') AndIf
- (token_break_char IsNot ' ') AndIf
- (token_break_char IsNot '\n')
- BeginWhile
- concat_char_to_string(next_token, token_break_char);
- If (Length(next_token) Is 2) AndIf (String(next_token)[0] Is '0') AndIf
- ((String(next_token)[1] Is 'x') OrIf (String(next_token)[1] Is 'X'))
- Then
- token_is_hex_number = True;
- Else
- If token_is_hex_number IsFalse
- Then
- token_is_number = token_is_number AndIf
- isdigit(token_break_char);
- If token_is_number
- Then
- token_numeric_value = (token_numeric_value * 10) +
- Bit_16(token_break_char - '0');
- EndIf;
- Else
- token_is_hex_number =
- token_is_number = token_is_number AndIf
- isxdigit(token_break_char);
- If token_is_number
- Then
- If isdigit(token_break_char)
- Then
- token_numeric_value = (token_numeric_value * 16) +
- Bit_16(token_break_char - '0');
- Else
- token_numeric_value = (token_numeric_value * 16) +
- Bit_16(toupper(token_break_char) - 'A' + 10);
- EndIf;
- EndIf;
- EndIf;
- EndIf;
- token_get_char();
- EndWhile;
- token_type = filename_token_type;
- break;
- EndCase;
- return;
- EndCode
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_help_switch |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_help_switch(switch_table_ptr current_switch)
- BeginDeclarations
- #define Affected_thing (*((boolean_switch_ptr)(*current_switch).affected_thing))
- FILE *help_file;
- EndDeclarations
- BeginCode
- Affected_thing.val = True;
- help_file = fopen(CharPtr(near_string(help_filename)), "r");
- If help_file IsNull
- Then
- printf("Could not open help file \"%Fs\".\n", String(help_filename));
- Else
- While fgets(CharPtr(object_file_element), MAX_ELEMENT_SIZE, help_file)
- IsNotNull
- BeginWhile
- fputs(CharPtr(object_file_element), stdout);
- If strcmp(CharPtr(object_file_element),
- "Press [RETURN] to continue.\n") IsZero
- Then
- gets(CharPtr(object_file_element));
- EndIf;
- EndWhile;
- fclose(help_file);
- EndIf;
- exit(0);
- return;
- EndCode
- #undef Affected_thing
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_reset_bit_16 |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_reset_bit_16(switch_table_ptr current_switch)
- BeginDeclarations
- #define Affected_thing (*((bit_16_switch_ptr)(*current_switch).affected_thing))
- EndDeclarations
- BeginCode
- scan_out_token();
- copy_string(token, next_token);
- Affected_thing.set = False;
- Affected_thing.val = Affected_thing.def;
- return;
- EndCode
- #undef Affected_thing
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_reset_switch |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_reset_switch(switch_table_ptr current_switch)
- BeginDeclarations
- #define Current_switch (*current_switch)
- #define Affected_thing (*((boolean_switch_ptr)(*current_switch).affected_thing))
- EndDeclarations
- BeginCode
- Affected_thing.val = False;
- scan_out_token();
- copy_string(token, next_token);
- return;
- EndCode
- #undef Current_switch
- #undef Affected_thing
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_set_switch |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_set_switch(switch_table_ptr current_switch)
- BeginDeclarations
- #define Current_switch (*current_switch)
- #define Affected_thing (*((boolean_switch_ptr)(*current_switch).affected_thing))
- EndDeclarations
- BeginCode
- Affected_thing.val = True;
- scan_out_token();
- copy_string(token, next_token);
- return;
- EndCode
- #undef Current_switch
- #undef Affected_thing
-
- /*+-------------------------------------------------------------------------+
- | |
- | scan_text_switch |
- | |
- +-------------------------------------------------------------------------+*/
- void scan_text_switch(switch_table_ptr current_switch)
- BeginDeclarations
- #define Current_switch (*current_switch)
- #define Affected_thing (*((text_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 token_type IsNot text_token_type
- Then
- linker_error(8, "Syntax error: Parenthesized text did not follow\n"
- "\t\"%s\" switch. Instead found \"%Fs\".\n",
- Current_switch.full_name, String(token));
- EndIf;
- Affected_thing.val = duplicate_string(Addr(static_pool), next_token);
- scan_out_token();
- copy_string(token, next_token);
- return;
- EndCode
- #undef Affected_thing
- #undef Current_switch
-
- /*+-------------------------------------------------------------------------+
- | |
- | token_get_char |
- | |
- +-------------------------------------------------------------------------+*/
- void token_get_char()
- BeginDeclarations
- int_16 c;
- token_stack_ptr tos;
- #define Tos (*tos)
- #define Tos_string (*tos).token_string
- EndDeclarations
- BeginCode
- Loop
- BeginLoop
- If ((*token_stack.first).source_file Is stdin) AndIf
- (prompt_next_stdin)
- Then
- linker_message("continue: ");
- prompt_next_stdin = False;
- EndIf;
- tos = token_stack.first;
- If tos IsNull
- Then
- token_break_char = ';';
- return;
- EndIf;
- If Tos.source_file IsNull
- Then /* Input is from a string */
- If Tos.token_string_index LessThan Length(Tos_string)
- Then
- token_break_char = String(Tos_string)[Tos.token_string_index++];
- ExitLoop;
- Else
- If token_stack.first Is token_stack.last
- Then
- token_break_char = '\n';
- return;
- Else
- Pop token_stack InTo tos EndPop;
- Push tos OnTo token_stack_free_list EndPush;
- ContinueLoop;
- EndIf;
- EndIf;
- Else /* Input is from a file */
- c = fgetc(Tos.source_file);
- If c Is EOF
- Then
- If Tos.source_file IsNot stdin
- Then
- fclose(Tos.source_file);
- EndIf;
- Pop token_stack InTo tos EndPop;
- token_break_char = Tos.break_char;
- Push tos OnTo token_stack_free_list EndPush;
- ExitLoop;
- Else
- token_break_char = Byte(c);
- ExitLoop;
- EndIf;
- EndIf;
- EndLoop;
- If token_break_char Is '\r'
- Then
- token_break_char = '\n';
- EndIf;
- If token_break_char Is '\t'
- Then
- token_break_char = ' ';
- EndIf;
- return;
- EndCode
- #undef Tos
- #undef Tos_string
-