*/
static void parse_error(const char *msg)
{
- errorf(lexer_token.source_position, "%s", msg);
+ errorf(&lexer_token.source_position, "%s", msg);
+}
+
+/**
+ * Prints an internal error message at the current token.
+ *
+ * @param msg the error message
+ */
+static NORETURN internal_error(const char *msg)
+{
+ internal_errorf(&lexer_token.source_position, "%s", msg);
}
static inline void next_real_char(void)
{
assert(bufpos <= bufend);
if (bufpos >= bufend) {
+ if (input == NULL) {
+ c = EOF;
+ return;
+ }
+
size_t s = fread(buf + MAX_PUTBACK, 1, sizeof(buf) - MAX_PUTBACK,
input);
if(s == 0) {
if(v >= TARGET_LONG_MIN && v <= TARGET_LONG_MAX) {
lexer_token.datatype = type_long;
return;
- } else if(is_oct_hex && v >= 0 && v <= TARGET_ULONG_MAX) {
+ } else if(is_oct_hex && v >= 0 && (unsigned long long)v <= (unsigned long long)TARGET_ULONG_MAX) {
lexer_token.datatype = type_unsigned_long;
return;
}
if(c == '.' || c == 'p' || c == 'P') {
next_char();
- panic("Hex floating point numbers not implemented yet");
+ internal_error("Hex floating point numbers not implemented yet");
}
if(*string == '\0') {
parse_error("invalid hex number");
case 'f':
case 'F': return 15;
default:
- panic("wrong character given");
+ internal_error("wrong character given");
}
}
source_position_t source_position;
source_position.input_name = lexer_token.source_position.input_name;
source_position.linenr = start_linenr;
- errorf(source_position, "string has no end");
+ errorf(&source_position, "string has no end");
lexer_token.type = T_ERROR;
return;
}
case EOF: {
source_position_t source_position = lexer_token.source_position;
source_position.linenr = start_linenr;
- errorf(source_position, "EOF while parsing character constant");
+ errorf(&source_position, "EOF while parsing character constant");
lexer_token.type = T_ERROR;
return;
}
end_of_wide_char_constant:;
size_t size = (size_t) obstack_object_size(&symbol_obstack);
+ assert(size % sizeof(wchar_rep_t) == 0);
+ size /= sizeof(wchar_rep_t);
+
const wchar_rep_t *string = obstack_finish(&symbol_obstack);
lexer_token.type = T_WIDE_CHARACTER_CONSTANT;
source_position_t source_position;
source_position.input_name = lexer_token.source_position.input_name;
source_position.linenr = start_linenr;
- errorf(source_position, "string has no end");
+ errorf(&source_position, "string has no end");
lexer_token.type = T_ERROR;
return;
}
source_position_t source_position;
source_position.input_name = lexer_token.source_position.input_name;
source_position.linenr = start_linenr;
- errorf(source_position, "EOF while parsing character constant");
+ errorf(&source_position, "EOF while parsing character constant");
lexer_token.type = T_ERROR;
return;
}
source_position_t source_position;
source_position.input_name = lexer_token.source_position.input_name;
source_position.linenr = start_linenr;
- errorf(source_position, "at end of file while looking for comment end");
+ errorf(&source_position, "at end of file while looking for comment end");
return;
}
/**
* STDC pragmas.
*/
-typedef enum {
+typedef enum stdc_pragma_kind_t {
STDC_UNKNOWN,
STDC_FP_CONTRACT,
STDC_FENV_ACCESS,
/**
* STDC pragma values.
*/
-typedef enum {
+typedef enum stdc_pragma_value_kind_t {
STDC_VALUE_UNKNOWN,
STDC_VALUE_ON,
STDC_VALUE_OFF,
if (value != STDC_VALUE_UNKNOWN) {
unknown_pragma = false;
} else {
- errorf(pp_token.source_position, "bad STDC pragma argument");
+ errorf(&pp_token.source_position, "bad STDC pragma argument");
}
}
}
}
eat_until_newline();
if (unknown_pragma && warning.unknown_pragmas) {
- warningf(pp_token.source_position, "encountered unknown #pragma");
+ warningf(&pp_token.source_position, "encountered unknown #pragma");
}
}
#define ELSE_CODE(code) \
default: \
- code; \
+ code \
} \
} /* end of while(1) */ \
break;
default:
next_char();
- errorf(lexer_token.source_position, "unknown character '%c' found\n", c);
+ errorf(&lexer_token.source_position, "unknown character '%c' found\n", c);
lexer_token.type = T_ERROR;
return;
}
void init_lexer(void)
{
strset_init(&stringset);
+ symbol_L = symbol_table_insert("L");
}
void lexer_open_stream(FILE *stream, const char *input_name)
lexer_token.source_position.linenr = 0;
lexer_token.source_position.input_name = input_name;
- symbol_L = symbol_table_insert("L");
bufpos = NULL;
bufend = NULL;
c = '\n';
}
+void lexer_open_buffer(const char *buffer, size_t len, const char *input_name)
+{
+ input = NULL;
+ lexer_token.source_position.linenr = 0;
+ lexer_token.source_position.input_name = input_name;
+
+ bufpos = buffer;
+ bufend = buffer + len;
+
+ /* place a virtual \n at the beginning so the lexer knows that we're
+ * at the beginning of a line */
+ c = '\n';
+}
+
void exit_lexer(void)
{
strset_destroy(&stringset);