/* This is the Assembler Pre-Processor
- Copyright (C) 1987-2018 Free Software Foundation, Inc.
+ Copyright (C) 1987-2022 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
static const char symver_pseudo[] = ".symver";
static const char * symver_state;
#endif
-#ifdef TC_ARM
+
static char last_char;
-#endif
static char lex[256];
static const char symbol_chars[] =
#if defined TC_ARM && defined OBJ_ELF
const char * symver_state;
#endif
-#ifdef TC_ARM
- char last_char;
-#endif
+ char last_char;
};
char *
#if defined TC_ARM && defined OBJ_ELF
saved->symver_state = symver_state;
#endif
-#ifdef TC_ARM
saved->last_char = last_char;
-#endif
/* do_scrub_begin() is not useful, just wastes time. */
#if defined TC_ARM && defined OBJ_ELF
symver_state = saved->symver_state;
#endif
-#ifdef TC_ARM
last_char = saved->last_char;
-#endif
free (arg);
}
}
}
+#define MULTIBYTE_WARN_COUNT_LIMIT 10
+static unsigned int multibyte_warn_count = 0;
+
+bool
+scan_for_multibyte_characters (const unsigned char * start,
+ const unsigned char * end,
+ bool warn)
+{
+ if (end <= start)
+ return false;
+
+ if (warn && multibyte_warn_count > MULTIBYTE_WARN_COUNT_LIMIT)
+ return false;
+
+ bool found = false;
+
+ while (start < end)
+ {
+ unsigned char c;
+
+ if ((c = * start++) <= 0x7f)
+ continue;
+
+ if (!warn)
+ return true;
+
+ found = true;
+
+ const char * filename;
+ unsigned int lineno;
+
+ filename = as_where (& lineno);
+ if (filename == NULL)
+ as_warn (_("multibyte character (%#x) encountered in input"), c);
+ else if (lineno == 0)
+ as_warn (_("multibyte character (%#x) encountered in %s"), c, filename);
+ else
+ as_warn (_("multibyte character (%#x) encountered in %s at or near line %u"), c, filename, lineno);
+
+ if (++ multibyte_warn_count == MULTIBYTE_WARN_COUNT_LIMIT)
+ {
+ as_warn (_("further multibyte character warnings suppressed"));
+ break;
+ }
+ }
+
+ return found;
+}
+
/* This function is called to process input characters. The GET
parameter is used to retrieve more input characters. GET should
set its parameter to point to a buffer, and return the length of
return 0;
from = input_buffer;
fromend = from + fromlen;
+
+ if (multibyte_handling == multibyte_warn)
+ (void) scan_for_multibyte_characters ((const unsigned char *) from,
+ (const unsigned char* ) fromend,
+ true /* Generate warnings. */);
}
while (1)
state = old_state;
PUT (ch);
}
-#ifndef NO_STRING_ESCAPES
- else if (ch == '\\')
+ else if (TC_STRING_ESCAPES && ch == '\\')
{
state = 6;
PUT (ch);
}
-#endif
else if (scrub_m68k_mri && ch == '\n')
{
/* Just quietly terminate the string. This permits lines like
}
else
{
+ if (ch != EOF)
+ UNGET (ch);
state = 9;
break;
}
}
#endif
if (IS_COMMENT (ch)
- || ch == '/'
|| IS_LINE_SEPARATOR (ch)
|| IS_PARALLEL_SEPARATOR (ch))
{
/* PUT didn't jump out. We could just break, but we
know what will happen, so optimize a bit. */
ch = GET ();
- old_state = 3;
+ old_state = 9;
}
- else if (state == 9)
- old_state = 3;
+ else if (state == 3)
+ old_state = 9;
else
old_state = state;
state = 5;
goto de_fault;
#endif
-#ifdef TC_ARM
- /* For the ARM, care is needed not to damage occurrences of \@
- by stripping the @ onwards. Yuck. */
+ /* Care is needed not to damage occurrences of \<comment-char>
+ by stripping the <comment-char> onwards. Yuck. */
if ((to > tostart ? to[-1] : last_char) == '\\')
- /* Do not treat the @ as a start-of-comment. */
+ /* Do not treat the <comment-char> as a start-of-comment. */
goto de_fault;
-#endif
#ifdef WARN_COMMENTS
if (!found_comment)
fromeof:
/* We have reached the end of the input. */
-#ifdef TC_ARM
if (to > tostart)
last_char = to[-1];
-#endif
return to - tostart;
tofull:
else
saved_input = NULL;
-#ifdef TC_ARM
if (to > tostart)
last_char = to[-1];
-#endif
return to - tostart;
}