/* Initialize line map */
linemap = yasm_linemap_create();
- yasm_linemap_set(linemap, in_filename, 1, 1);
+ yasm_linemap_set(linemap, in_filename, 0, 1, 1);
/* determine the object filename if not specified */
if (!obj_filename) {
/* Initialize line map */
linemap = yasm_linemap_create();
- yasm_linemap_set(linemap, in_filename, 1, 1);
+ yasm_linemap_set(linemap, in_filename, 0, 1, 1);
/* Default output to stdout if not specified or generating dependency
makefiles */
/* Initialize line map */
linemap = yasm_linemap_create();
- yasm_linemap_set(linemap, in_filename, 1, 1);
+ yasm_linemap_set(linemap, in_filename, 0, 1, 1);
/* determine the object filename if not specified */
if (!obj_filename) {
void
yasm_linemap_set(yasm_linemap *linemap, const char *filename,
- unsigned long file_line, unsigned long line_inc)
+ unsigned long virtual_line, unsigned long file_line,
+ unsigned long line_inc)
{
char *copy;
+ unsigned long i;
int replace = 0;
- line_mapping *mapping;
+ line_mapping *mapping = NULL;
- /* Create a new mapping in the map */
- if (linemap->map_size >= linemap->map_allocated) {
- /* allocate another size bins when full for 2x space */
- linemap->map_vector =
- yasm_xrealloc(linemap->map_vector, 2*linemap->map_allocated
- *sizeof(line_mapping));
- linemap->map_allocated *= 2;
+ if (virtual_line == 0) {
+ virtual_line = linemap->current;
+ }
+
+ /* Replace all existing mappings that have line numbers >= this one. */
+ for (i = linemap->map_size; i > 0; i--) {
+ if (linemap->map_vector[i-1].line < virtual_line) {
+ if (i < linemap->map_size) {
+ mapping = &linemap->map_vector[i];
+ linemap->map_size = i + 1;
+ }
+ break;
+ }
+ }
+
+ if (mapping == NULL) {
+ /* Create a new mapping in the map */
+ if (linemap->map_size >= linemap->map_allocated) {
+ /* allocate another size bins when full for 2x space */
+ linemap->map_vector = yasm_xrealloc(linemap->map_vector,
+ 2*linemap->map_allocated*sizeof(line_mapping));
+ linemap->map_allocated *= 2;
+ }
+ mapping = &linemap->map_vector[linemap->map_size];
+ linemap->map_size++;
}
- mapping = &linemap->map_vector[linemap->map_size];
- linemap->map_size++;
/* Fill it */
/*@=aliasunique@*/
}
- mapping->line = linemap->current;
+ mapping->line = virtual_line;
mapping->file_line = file_line;
mapping->line_inc = line_inc;
}
line_mapping *mapping;
linemap->current++;
- yasm_linemap_set(linemap, filename, file_line, 0);
+ yasm_linemap_set(linemap, filename, 0, file_line, 0);
mapping = &linemap->map_vector[linemap->map_size-1];
line = linemap->current;
linemap->current++;
- yasm_linemap_set(linemap, mapping->filename,
+ yasm_linemap_set(linemap, mapping->filename, 0,
mapping->file_line +
mapping->line_inc*(linemap->current-2-mapping->line),
mapping->line_inc);
mapping = &linemap->map_vector[vindex];
*filename = mapping->filename;
- *file_line = mapping->file_line + mapping->line_inc*(line-mapping->line);
+ *file_line = (line ? mapping->file_line + mapping->line_inc*(line-mapping->line) : 0);
}
int
YASM_LIB_DECL
unsigned long yasm_linemap_goto_next(yasm_linemap *linemap);
-/** Set a new file/line physical association starting point at the current
+/** Set a new file/line physical association starting point at the specified
* virtual line. line_inc indicates how much the "real" line is incremented
* by for each virtual line increment (0 is perfectly legal).
* \param linemap line mapping repository
* \param filename physical file name (if NULL, not changed)
+ * \param virtual_line virtual line number (if 0, linemap->current is used)
* \param file_line physical line number
* \param line_inc line increment
*/
YASM_LIB_DECL
void yasm_linemap_set(yasm_linemap *linemap, /*@null@*/ const char *filename,
- unsigned long file_line, unsigned long line_inc);
+ unsigned long virtual_line, unsigned long file_line,
+ unsigned long line_inc);
/** Poke a single file/line association, restoring the original physical
* association starting point. Caution: increments the current virtual line
get_next_token();
/* Set linemap. */
- yasm_linemap_set(parser_gas->linemap, filename, line, 1);
+ yasm_linemap_set(parser_gas->linemap, filename, 0, line, 1);
/*
The first line marker in the file (which should be on the first line
filename = STRING_val.contents;
/* Set linemap. */
- yasm_linemap_set(parser_gas->linemap, filename, line, incr);
+ yasm_linemap_set(parser_gas->linemap, filename, 0, line, incr);
/*
The first line marker in the file (which should be on the first line
if (parser_gas->dir_fileline == 3) {
/* Have both file and line */
- yasm_linemap_set(parser_gas->linemap, NULL,
+ yasm_linemap_set(parser_gas->linemap, NULL, 0,
parser_gas->dir_line, 1);
} else if (parser_gas->dir_fileline == 1) {
/* Had previous file directive only */
parser_gas->dir_fileline = 3;
- yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file,
+ yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file, 0,
parser_gas->dir_line, 1);
} else {
/* Didn't see file yet */
yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn,
&old_line);
- yasm_linemap_set(parser_gas->linemap, filename, old_line,
+ yasm_linemap_set(parser_gas->linemap, filename, 0, old_line,
1);
} else if (parser_gas->dir_fileline == 2) {
/* Had previous line directive only */
parser_gas->dir_fileline = 3;
- yasm_linemap_set(parser_gas->linemap, filename,
+ yasm_linemap_set(parser_gas->linemap, filename, 0,
parser_gas->dir_line, 1);
} else {
/* Didn't see line yet, save file */
/* %line indicates the line number of the *next* line, so subtract
* out the increment when setting the line number.
*/
- yasm_linemap_set(parser_nasm->linemap, filename,
+ yasm_linemap_set(parser_nasm->linemap, filename, 0,
yasm_intnum_get_uint(line) - yasm_intnum_get_uint(incr),
yasm_intnum_get_uint(incr));
yasm_intnum_destroy(line);