enum gas_parser_state newstate;
} dir_lookup;
-static yasm_bytecode * cpp_line_marker(yasm_parser_gas *parser_gas);
+static void cpp_line_marker(yasm_parser_gas *parser_gas);
+static void nasm_line_marker(yasm_parser_gas *parser_gas);
static yasm_bytecode *parse_instr(yasm_parser_gas *parser_gas);
static int parse_dirvals(yasm_parser_gas *parser_gas, yasm_valparamhead *vps);
static int parse_datavals(yasm_parser_gas *parser_gas, yasm_datavalhead *dvs);
define_label(parser_gas, LABEL_val, 0);
get_next_token(); /* LABEL */
return parse_line(parser_gas);
- case LINE_MARKER:
+ case CPP_LINE_MARKER:
get_next_token();
- return cpp_line_marker(parser_gas);
+ cpp_line_marker(parser_gas);
+ return NULL;
+ case NASM_LINE_MARKER:
+ get_next_token();
+ nasm_line_marker(parser_gas);
+ return NULL;
default:
yasm_error_set(YASM_ERROR_SYNTAX,
N_("label or instruction expected at start of line"));
without adding a filter to the input before passing it to cpp.
This function is only called if the preprocessor was 'cpp', since the
- LINE_MARKER token isn't generated for any other preprocessor. With any other
- preprocessor, anything after a '#' is always treated as a comment.
+ CPP_LINE_MARKER token isn't generated for any other preprocessor. With any
+ other preprocessor, anything after a '#' is always treated as a comment.
*/
-static yasm_bytecode *
+static void
cpp_line_marker(yasm_parser_gas *parser_gas)
{
yasm_valparamhead vps;
while (curtok != '\n')
get_next_token();
- return NULL;
+ return;
}
if (yasm_intnum_sign(INTNUM_val) < 0) {
get_next_token(); /* INTNUM */
yasm_error_set(YASM_ERROR_SYNTAX,
N_("line number is negative"));
- return NULL;
+ return;
}
line = yasm_intnum_get_uint(INTNUM_val);
while (curtok != '\n')
get_next_token();
- return NULL;
+ return;
}
filename = STRING_val.contents;
yasm_object_directive(p_object, ".file", "gas", &vps, NULL, cur_line);
yasm_vps_delete(&vps);
- }
+ } else
+ yasm_xfree(filename);
/* Skip flags. */
while (1) {
break;
case '\n':
- return NULL;
+ return;
default:
yasm_error_set(YASM_ERROR_SYNTAX,
N_("junk at end of cpp line marker"));
- return NULL;
+ return;
}
get_next_token();
}
+}
- /* Never reached. */
- return NULL;
+/*
+ Handle line markers generated by the nasm preproc.
+
+ We expect a positive integer (line) followed by a plus sign, followed by
+ another positive integer, followed by a string (filename).
+
+ This function is only called if the preprocessor was 'nasm', since the
+ NASM_LINE_MARKER token isn't generated for any other preprocessor.
+*/
+static void
+nasm_line_marker(yasm_parser_gas *parser_gas)
+{
+ yasm_valparamhead vps;
+ yasm_valparam *vp;
+ unsigned long line, incr;
+ char *filename;
+
+ /* Line number. */
+ if (!expect(INTNUM)) return;
+
+ if (yasm_intnum_sign(INTNUM_val) < 0) {
+ get_next_token(); /* INTNUM */
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("line number is negative"));
+ return;
+ }
+
+ line = yasm_intnum_get_uint(INTNUM_val);
+
+ yasm_intnum_destroy(INTNUM_val);
+ get_next_token(); /* INTNUM */
+
+ if (!expect('+')) return;
+ get_next_token(); /* + */
+
+ /* Line number increment. */
+ if (!expect(INTNUM)) return;
+
+ if (yasm_intnum_sign(INTNUM_val) < 0) {
+ get_next_token(); /* INTNUM */
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("line increment is negative"));
+ return;
+ }
+
+ incr = yasm_intnum_get_uint(INTNUM_val);
+ yasm_intnum_destroy(INTNUM_val);
+
+ /* File name is not in quotes, so need to switch to a different tokenizer
+ * state.
+ */
+ parser_gas->state = NASM_FILENAME;
+ get_next_token(); /* INTNUM */
+ if (!expect(STRING)) {
+ parser_gas->state = INITIAL;
+ return;
+ }
+
+ filename = STRING_val.contents;
+ get_next_token(); /* STRING */
+
+ /* Set linemap. */
+ yasm_linemap_set(parser_gas->linemap, filename, line, incr);
+
+ /*
+ The first line marker in the file (which should be on the first line
+ of the file) will give us the name of the source file. This information
+ needs to be passed on to the debug format module.
+ */
+ if (parser_gas->seen_line_marker == 0) {
+ parser_gas->seen_line_marker = 1;
+
+ yasm_vps_initialize(&vps);
+ vp = yasm_vp_create_string(NULL, filename);
+ yasm_vps_append(&vps, vp);
+
+ yasm_object_directive(p_object, ".file", "gas", &vps, NULL, cur_line);
+
+ yasm_vps_delete(&vps);
+ } else
+ yasm_xfree(filename);
}
/* Line directive */
goto comment;
case SECTION_DIRECTIVE:
goto section_directive;
+ case NASM_FILENAME:
+ goto nasm_filename;
default:
break;
}
[%][a-zA-Z0-9]+ {
savech = s->tok[TOKLEN];
s->tok[TOKLEN] = '\0';
+ if (parser_gas->is_nasm_preproc && strcmp(TOK+1, "line") == 0) {
+ s->tok[TOKLEN] = savech;
+ RETURN(NASM_LINE_MARKER);
+ }
+
switch (yasm_arch_parse_check_regtmod
(p_object->arch, TOK+1, TOKLEN-1, &lvalp->arch_data)) {
case YASM_ARCH_REG:
"/*" { parser_gas->state = COMMENT; goto comment; }
"#" {
- if (strcmp(((yasm_preproc_base*)parser_gas->preproc)->module->keyword,
- "cpp") == 0)
+ if (parser_gas->is_cpp_preproc)
{
- RETURN(LINE_MARKER);
+ RETURN(CPP_LINE_MARKER);
} else
goto line_comment;
}
}
*/
+ /* filename portion of nasm preproc %line */
+nasm_filename:
+ strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE);
+ strbuf_size = STRBUF_ALLOC_SIZE;
+ count = 0;
+
+nasm_filename_scan:
+ SCANINIT();
+
+ /*!re2c
+ "\n" {
+ strbuf_append(count++, cursor, s, '\0');
+ lvalp->str.contents = (char *)strbuf;
+ lvalp->str.len = count;
+ parser_gas->state = INITIAL;
+ RETURN(STRING);
+ }
+
+ ws+ { goto nasm_filename_scan; }
+
+ any {
+ if (cursor == s->eof) {
+ strbuf_append(count++, cursor, s, '\0');
+ lvalp->str.contents = (char *)strbuf;
+ lvalp->str.len = count;
+ parser_gas->state = INITIAL;
+ RETURN(STRING);
+ }
+ strbuf_append(count++, cursor, s, s->tok[0]);
+ goto nasm_filename_scan;
+ }
+ */
+
/* character constant values */
charconst:
/*TODO*/