📄 read.c
字号:
this file as the "main" source file and not a subordinate one (e.g. N_SO vs N_SOL in stabs). */ generate_file_debug (); while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0) { /* We have another line to parse. */ know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */ contin: /* JF this goto is my fault I admit it. Someone brave please re-write the whole input section here? Pleeze??? */ while (input_line_pointer < buffer_limit) { /* We have more of this buffer to parse. */ /* We now have input_line_pointer->1st char of next line. If input_line_pointer [-1] == '\n' then we just scanned another line: so bump line counters. */ if (is_end_of_line[(unsigned char) input_line_pointer[-1]]) {#ifdef md_start_line_hook md_start_line_hook ();#endif if (input_line_pointer[-1] == '\n') bump_line_counters (); line_label = NULL; if (LABELS_WITHOUT_COLONS || flag_m68k_mri) { /* Text at the start of a line must be a label, we run down and stick a colon in. */ if (is_name_beginner (*input_line_pointer)) { char *line_start = input_line_pointer; char c; int mri_line_macro; LISTING_NEWLINE (); HANDLE_CONDITIONAL_ASSEMBLY (); c = get_symbol_end (); /* In MRI mode, the EQU and MACRO pseudoops must be handled specially. */ mri_line_macro = 0; if (flag_m68k_mri) { char *rest = input_line_pointer + 1; if (*rest == ':') ++rest; if (*rest == ' ' || *rest == '\t') ++rest; if ((strncasecmp (rest, "EQU", 3) == 0 || strncasecmp (rest, "SET", 3) == 0) && (rest[3] == ' ' || rest[3] == '\t')) { input_line_pointer = rest + 3; equals (line_start, strncasecmp (rest, "SET", 3) == 0); continue; } if (strncasecmp (rest, "MACRO", 5) == 0 && (rest[5] == ' ' || rest[5] == '\t' || is_end_of_line[(unsigned char) rest[5]])) mri_line_macro = 1; } /* In MRI mode, we need to handle the MACRO pseudo-op specially: we don't want to put the symbol in the symbol table. */ if (!mri_line_macro#ifdef TC_START_LABEL_WITHOUT_COLON && TC_START_LABEL_WITHOUT_COLON(c, input_line_pointer)#endif ) line_label = colon (line_start); else line_label = symbol_create (line_start, absolute_section, (valueT) 0, &zero_address_frag); *input_line_pointer = c; if (c == ':') input_line_pointer++; } } } /* We are at the begining of a line, or similar place. We expect a well-formed assembler statement. A "symbol-name:" is a statement. Depending on what compiler is used, the order of these tests may vary to catch most common case 1st. Each test is independent of all other tests at the (top) level. PLEASE make a compiler that doesn't use this assembler. It is crufty to waste a compiler's time encoding things for this assembler, which then wastes more time decoding it. (And communicating via (linear) files is silly! If you must pass stuff, please pass a tree!) */ if ((c = *input_line_pointer++) == '\t' || c == ' ' || c == '\f' || c == 0) c = *input_line_pointer++; know (c != ' '); /* No further leading whitespace. */#ifndef NO_LISTING /* If listing is on, and we are expanding a macro, then give the listing code the contents of the expanded line. */ if (listing) { if ((listing & LISTING_MACEXP) && macro_nest > 0) { char *copy; int len; /* Find the end of the current expanded macro line. */ for (s = input_line_pointer - 1; *s; ++s) if (is_end_of_line[(unsigned char) *s]) break; /* Copy it for safe keeping. Also give an indication of how much macro nesting is involved at this point. */ len = s - (input_line_pointer - 1); copy = (char *) xmalloc (len + macro_nest + 2); memset (copy, '>', macro_nest); copy[macro_nest] = ' '; memcpy (copy + macro_nest + 1, input_line_pointer - 1, len); copy[macro_nest + 1 + len] = '\0'; /* Install the line with the listing facility. */ listing_newline (copy); } else listing_newline (NULL); }#endif /* C is the 1st significant character. Input_line_pointer points after that character. */ if (is_name_beginner (c)) { /* Want user-defined label or pseudo/opcode. */ HANDLE_CONDITIONAL_ASSEMBLY (); s = --input_line_pointer; c = get_symbol_end (); /* name's delimiter. */ /* C is character after symbol. That character's place in the input line is now '\0'. S points to the beginning of the symbol. [In case of pseudo-op, s->'.'.] Input_line_pointer->'\0' where c was. */ if (TC_START_LABEL (c, input_line_pointer)) { if (flag_m68k_mri) { char *rest = input_line_pointer + 1; /* In MRI mode, \tsym: set 0 is permitted. */ if (*rest == ':') ++rest; if (*rest == ' ' || *rest == '\t') ++rest; if ((strncasecmp (rest, "EQU", 3) == 0 || strncasecmp (rest, "SET", 3) == 0) && (rest[3] == ' ' || rest[3] == '\t')) { input_line_pointer = rest + 3; equals (s, 1); continue; } } line_label = colon (s); /* User-defined label. */ /* Put ':' back for error messages' sake. */ *input_line_pointer++ = ':'; /* Input_line_pointer->after ':'. */ SKIP_WHITESPACE (); } else if (c == '=' || ((c == ' ' || c == '\t') && input_line_pointer[1] == '='#ifdef TC_EQUAL_IN_INSN && !TC_EQUAL_IN_INSN (c, input_line_pointer)#endif )) { equals (s, 1); demand_empty_rest_of_line (); } else { /* Expect pseudo-op or machine instruction. */ pop = NULL;#ifdef IGNORE_OPCODE_CASE { char *s2 = s; strncpy (original_case_string, s2, sizeof (original_case_string)); original_case_string[sizeof (original_case_string) - 1] = 0; while (*s2) { if (isupper ((unsigned char) *s2)) *s2 = tolower (*s2); s2++; } }#endif if (NO_PSEUDO_DOT || flag_m68k_mri) { /* The MRI assembler and the m88k use pseudo-ops without a period. */ pop = (pseudo_typeS *) hash_find (po_hash, s); if (pop != NULL && pop->poc_handler == NULL) pop = NULL; } if (pop != NULL || (!flag_m68k_mri && *s == '.')) { /* PSEUDO - OP. WARNING: c has next char, which may be end-of-line. We lookup the pseudo-op table with s+1 because we already know that the pseudo-op begins with a '.'. */ if (pop == NULL) pop = (pseudo_typeS *) hash_find (po_hash, s + 1); /* In MRI mode, we may need to insert an automatic alignment directive. What a hack this is. */ if (mri_pending_align && (pop == NULL || !((pop->poc_handler == cons && pop->poc_val == 1) || (pop->poc_handler == s_space && pop->poc_val == 1)#ifdef tc_conditional_pseudoop || tc_conditional_pseudoop (pop)#endif || pop->poc_handler == s_if || pop->poc_handler == s_ifdef || pop->poc_handler == s_ifc || pop->poc_handler == s_ifeqs || pop->poc_handler == s_else || pop->poc_handler == s_endif || pop->poc_handler == s_globl || pop->poc_handler == s_ignore))) { do_align (1, (char *) NULL, 0, 0); mri_pending_align = 0; if (line_label != NULL) { symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } /* Print the error msg now, while we still can. */ if (pop == NULL) { as_bad (_("Unknown pseudo-op: `%s'"), s); *input_line_pointer = c; s_ignore (0); continue; } /* Put it back for error messages etc. */ *input_line_pointer = c; /* The following skip of whitespace is compulsory. A well shaped space is sometimes all that separates keyword from operands. */ if (c == ' ' || c == '\t') input_line_pointer++; /* Input_line is restored. Input_line_pointer->1st non-blank char after pseudo-operation. */ (*pop->poc_handler) (pop->poc_val); /* If that was .end, just get out now. */ if (pop->poc_handler == s_end) goto quit; } else { int inquote = 0;#ifdef QUOTES_IN_INSN int inescape = 0;#endif /* WARNING: c has char, which may be end-of-line. */ /* Also: input_line_pointer->`\0` where c was. */ *input_line_pointer = c; while (!is_end_of_line[(unsigned char) *input_line_pointer] || inquote#ifdef TC_EOL_IN_INSN || TC_EOL_IN_INSN (input_line_pointer)#endif ) { if (flag_m68k_mri && *input_line_pointer == '\'') inquote = !inquote;#ifdef QUOTES_IN_INSN if (inescape) inescape = 0; else if (*input_line_pointer == '"') inquote = !inquote; else if (*input_line_pointer == '\\') inescape = 1;#endif input_line_pointer++; } c = *input_line_pointer; *input_line_pointer = '\0'; generate_lineno_debug (); if (macro_defined) { sb out; const char *err; macro_entry *macro; if (check_macro (s, &out, '\0', &err, ¯o)) { if (err != NULL) as_bad ("%s", err); *input_line_pointer++ = c; input_scrub_include_sb (&out, input_line_pointer, 1); sb_kill (&out); buffer_limit = input_scrub_next_buffer (&input_line_pointer);#ifdef md_macro_info md_macro_info (macro);#endif continue; } } if (mri_pending_align) { do_align (1, (char *) NULL, 0, 0); mri_pending_align = 0; if (line_label != NULL) { symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } md_assemble (s); /* Assemble 1 instruction. */ *input_line_pointer++ = c; /* We resume loop AFTER the end-of-line from this instruction. */ } } continue; } /* Empty statement? */ if (is_end_of_line[(unsigned char) c]) continue; if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && isdigit ((unsigned char) c)) { /* local label ("4:") */ char *backup = input_line_pointer; HANDLE_CONDITIONAL_ASSEMBLY (); temp = c - '0'; /* Read the whole number. */ while (isdigit ((unsigned char) *input_line_pointer)) { temp = (temp * 10) + *input_line_pointer - '0'; ++input_line_pointer; } if (LOCAL_LABELS_DOLLAR && *input_line_pointer == '$' && *(input_line_pointer + 1) == ':') { input_line_pointer += 2; if (dollar_label_defined (temp)) { as_fatal (_("label \"%d$\" redefined"), temp); } define_dollar_label (temp); colon (dollar_label_name (temp, 0)); continue; } if (LOCAL_LABELS_FB && *input_line_pointer++ == ':') { fb_label_instance_inc (temp); colon (fb_label_name (temp, 0)); continue; } input_line_pointer = backup; } /* local label ("4:") */ if (c && strchr (line_comment_chars, c)) { /* Its a comment. Better say APP or NO_APP. */ char *ends; char *new_buf; char *new_tmp; unsigned int new_length; char *tmp_buf = 0; bump_line_counters (); s = input_line_pointer; if (strncmp (s, "APP\n", 4)) continue; /* We ignore it */ s += 4; ends = strstr (s, "#NO_APP\n"); if (!ends) { unsigned int tmp_len; unsigned int num; /* The end of the #APP wasn't in this buffer. We keep reading in buffers until we find the #NO_APP that goes with this #APP There is one. The specs guarentee it... */ tmp_len = buffer_limit - s; tmp_buf = xmalloc (tmp_len + 1); memcpy (tmp_buf, s, tmp_len); do { new_tmp = input_scrub_next_buffer (&buffer); if (!new_tmp) break; else buffer_limit = new_tmp; input_line_pointer = buffer; ends = strstr (buffer, "#NO_APP\n"); if (ends) num = ends - buffer; else num = buffer_limit - buffer; tmp_buf = xrealloc (tmp_buf, tmp_len + num); memcpy (tmp_buf + tmp_len, buffer, num); tmp_len += num; } while (!ends); input_line_pointer = ends ? ends + 8 : NULL; s = tmp_buf; ends = s + tmp_len; } else { input_line_pointer = ends + 8; } scrub_string = s; scrub_string_end = ends; new_length = ends - s; new_buf = (char *) xmalloc (new_length); new_tmp = new_buf; for (;;) { int space; int size; space = (new_buf + new_length) - new_tmp; size = do_scrub_chars (scrub_from_string, new_tmp, space); if (size < space) { new_tmp += size; break; } new_buf = xrealloc (new_buf, new_length + 100); new_tmp = new_buf + new_length; new_length += 100; } if (tmp_buf) free (tmp_buf); old_buffer = buffer; old_input = input_line_pointer; old_limit = buffer_limit; buffer = new_buf; input_line_pointer = new_buf; buffer_limit = new_tmp; continue; } HANDLE_CONDITIONAL_ASSEMBLY ();#ifdef tc_unrecognized_line if (tc_unrecognized_line (c)) continue;#endif /* as_warn (_("Junk character %d."),c); Now done by ignore_rest. */ input_line_pointer--; /* Report unknown char as ignored. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -