From 7b4e6c09dc95e575f975e10744a48f99085bcf44 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sun, 2 Dec 2001 20:12:04 +0000 Subject: [PATCH] Add support for NASM's %line. svn path=/trunk/yasm/; revision=376 --- libyasm/linemgr.c | 1 + libyasm/linemgr.h | 7 +++++++ modules/parsers/nasm/bison.y.in | 15 +++++++++++++-- modules/parsers/nasm/nasm-bison.y | 15 +++++++++++++-- modules/parsers/nasm/token.l.in | 25 ++++++++++++++++++++++++- src/globals.c | 1 + src/globals.h | 7 +++++++ src/linemgr.c | 1 + src/linemgr.h | 7 +++++++ src/parsers/nasm/bison.y.in | 15 +++++++++++++-- src/parsers/nasm/nasm-bison.y | 15 +++++++++++++-- src/parsers/nasm/token.l.in | 25 ++++++++++++++++++++++++- 12 files changed, 124 insertions(+), 10 deletions(-) diff --git a/libyasm/linemgr.c b/libyasm/linemgr.c index 10d87f5f..bcdd65e3 100644 --- a/libyasm/linemgr.c +++ b/libyasm/linemgr.c @@ -35,6 +35,7 @@ /*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL; unsigned int line_number = 1; +unsigned int line_number_inc = 1; unsigned int asm_options = 0; int indent_level = 0; diff --git a/libyasm/linemgr.h b/libyasm/linemgr.h index 4ae8532c..be2fcf43 100644 --- a/libyasm/linemgr.h +++ b/libyasm/linemgr.h @@ -30,6 +30,13 @@ extern /*@null@*/ objfmt *cur_objfmt; /*@null@*/ /*@dependent@*/ extern const char *in_filename; extern unsigned int line_number; + +/* Amount to increase line_number by after each line. Should be 0 or 1, set by + * %line (in NASM syntax). Initialized to 1 at startup. + * (0 is for 1-line macros that expand to multiple lines). + */ +extern unsigned int line_number_inc; + extern unsigned int asm_options; extern int indent_level; diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index af3c34ac..66d913c7 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -84,7 +84,7 @@ static bytecode *nasm_parser_temp_bc; %token INTNUM %token FLTNUM -%token DIRECTIVE_NAME STRING +%token DIRECTIVE_NAME STRING FILENAME %token BYTE WORD DWORD QWORD TWORD DQWORD %token DECLARE_DATA %token RESERVE_SPACE @@ -101,6 +101,7 @@ static bytecode *nasm_parser_temp_bc; %token REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID %token ID LOCAL_ID SPECIAL_ID +%token LINE /* instruction tokens (dynamically generated) */ /* @TOKENS@ */ @@ -144,12 +145,22 @@ input: /* empty */ $2); if (nasm_parser_temp_bc) nasm_parser_prev_bc = nasm_parser_temp_bc; - line_number++; + line_number += line_number_inc; } ; line: '\n' { $$ = (bytecode *)NULL; } | lineexp '\n' + | LINE INTNUM '+' INTNUM FILENAME '\n' { + line_number = intnum_get_uint($2); + line_number_inc = intnum_get_uint($4); + line_number -= line_number_inc; /* as we'll add it back in */ + switch_filename($5); + intnum_delete($2); + intnum_delete($4); + xfree($5); + $$ = (bytecode *)NULL; + } | directive '\n' { $$ = (bytecode *)NULL; } | error '\n' { Error(_("label or instruction expected at start of line")); diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index af3c34ac..66d913c7 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -84,7 +84,7 @@ static bytecode *nasm_parser_temp_bc; %token INTNUM %token FLTNUM -%token DIRECTIVE_NAME STRING +%token DIRECTIVE_NAME STRING FILENAME %token BYTE WORD DWORD QWORD TWORD DQWORD %token DECLARE_DATA %token RESERVE_SPACE @@ -101,6 +101,7 @@ static bytecode *nasm_parser_temp_bc; %token REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID %token ID LOCAL_ID SPECIAL_ID +%token LINE /* instruction tokens (dynamically generated) */ /* @TOKENS@ */ @@ -144,12 +145,22 @@ input: /* empty */ $2); if (nasm_parser_temp_bc) nasm_parser_prev_bc = nasm_parser_temp_bc; - line_number++; + line_number += line_number_inc; } ; line: '\n' { $$ = (bytecode *)NULL; } | lineexp '\n' + | LINE INTNUM '+' INTNUM FILENAME '\n' { + line_number = intnum_get_uint($2); + line_number_inc = intnum_get_uint($4); + line_number -= line_number_inc; /* as we'll add it back in */ + switch_filename($5); + intnum_delete($2); + intnum_delete($4); + xfree($5); + $$ = (bytecode *)NULL; + } | directive '\n' { $$ = (bytecode *)NULL; } | error '\n' { Error(_("label or instruction expected at start of line")); diff --git a/modules/parsers/nasm/token.l.in b/modules/parsers/nasm/token.l.in index bcaf5aa9..d3524673 100644 --- a/modules/parsers/nasm/token.l.in +++ b/modules/parsers/nasm/token.l.in @@ -60,12 +60,14 @@ static size_t strbuf_size = 0; /* last "base" label for local (.) labels */ char *nasm_parser_locallabel_base = (char *)NULL; +static int linechg_numcount; + %} %option noyywrap %option nounput %option case-insensitive -%x DIRECTIVE +%x DIRECTIVE LINECHG LINECHG2 %s DIRECTIVE2 DIGIT [0-9] @@ -150,6 +152,27 @@ WS [ \t\r] return STRING; } + /* %line linenum+lineinc filename */ +^%line { BEGIN LINECHG; linechg_numcount = 0; return LINE; } +{DIGIT}+ { + linechg_numcount++; + yylval.intn = intnum_new_dec(yytext); + return INTNUM; +} +\n { BEGIN INITIAL; return '\n'; } +[+] { return yytext[0]; } +{WS}+ { + if (linechg_numcount == 2) + BEGIN LINECHG2; +} +\n { BEGIN INITIAL; return '\n'; } +\r ; +[^\r\n]+ { + BEGIN LINECHG; + yylval.str_val = xstrdup(yytext); + return FILENAME; +} + /* directive: [name value] */ ^{WS}*"[" { BEGIN DIRECTIVE; return '['; } "]" { BEGIN INITIAL; return ']'; } diff --git a/src/globals.c b/src/globals.c index 10d87f5f..bcdd65e3 100644 --- a/src/globals.c +++ b/src/globals.c @@ -35,6 +35,7 @@ /*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL; unsigned int line_number = 1; +unsigned int line_number_inc = 1; unsigned int asm_options = 0; int indent_level = 0; diff --git a/src/globals.h b/src/globals.h index 4ae8532c..be2fcf43 100644 --- a/src/globals.h +++ b/src/globals.h @@ -30,6 +30,13 @@ extern /*@null@*/ objfmt *cur_objfmt; /*@null@*/ /*@dependent@*/ extern const char *in_filename; extern unsigned int line_number; + +/* Amount to increase line_number by after each line. Should be 0 or 1, set by + * %line (in NASM syntax). Initialized to 1 at startup. + * (0 is for 1-line macros that expand to multiple lines). + */ +extern unsigned int line_number_inc; + extern unsigned int asm_options; extern int indent_level; diff --git a/src/linemgr.c b/src/linemgr.c index 10d87f5f..bcdd65e3 100644 --- a/src/linemgr.c +++ b/src/linemgr.c @@ -35,6 +35,7 @@ /*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL; unsigned int line_number = 1; +unsigned int line_number_inc = 1; unsigned int asm_options = 0; int indent_level = 0; diff --git a/src/linemgr.h b/src/linemgr.h index 4ae8532c..be2fcf43 100644 --- a/src/linemgr.h +++ b/src/linemgr.h @@ -30,6 +30,13 @@ extern /*@null@*/ objfmt *cur_objfmt; /*@null@*/ /*@dependent@*/ extern const char *in_filename; extern unsigned int line_number; + +/* Amount to increase line_number by after each line. Should be 0 or 1, set by + * %line (in NASM syntax). Initialized to 1 at startup. + * (0 is for 1-line macros that expand to multiple lines). + */ +extern unsigned int line_number_inc; + extern unsigned int asm_options; extern int indent_level; diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index af3c34ac..66d913c7 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -84,7 +84,7 @@ static bytecode *nasm_parser_temp_bc; %token INTNUM %token FLTNUM -%token DIRECTIVE_NAME STRING +%token DIRECTIVE_NAME STRING FILENAME %token BYTE WORD DWORD QWORD TWORD DQWORD %token DECLARE_DATA %token RESERVE_SPACE @@ -101,6 +101,7 @@ static bytecode *nasm_parser_temp_bc; %token REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID %token ID LOCAL_ID SPECIAL_ID +%token LINE /* instruction tokens (dynamically generated) */ /* @TOKENS@ */ @@ -144,12 +145,22 @@ input: /* empty */ $2); if (nasm_parser_temp_bc) nasm_parser_prev_bc = nasm_parser_temp_bc; - line_number++; + line_number += line_number_inc; } ; line: '\n' { $$ = (bytecode *)NULL; } | lineexp '\n' + | LINE INTNUM '+' INTNUM FILENAME '\n' { + line_number = intnum_get_uint($2); + line_number_inc = intnum_get_uint($4); + line_number -= line_number_inc; /* as we'll add it back in */ + switch_filename($5); + intnum_delete($2); + intnum_delete($4); + xfree($5); + $$ = (bytecode *)NULL; + } | directive '\n' { $$ = (bytecode *)NULL; } | error '\n' { Error(_("label or instruction expected at start of line")); diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index af3c34ac..66d913c7 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -84,7 +84,7 @@ static bytecode *nasm_parser_temp_bc; %token INTNUM %token FLTNUM -%token DIRECTIVE_NAME STRING +%token DIRECTIVE_NAME STRING FILENAME %token BYTE WORD DWORD QWORD TWORD DQWORD %token DECLARE_DATA %token RESERVE_SPACE @@ -101,6 +101,7 @@ static bytecode *nasm_parser_temp_bc; %token REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS %token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID %token ID LOCAL_ID SPECIAL_ID +%token LINE /* instruction tokens (dynamically generated) */ /* @TOKENS@ */ @@ -144,12 +145,22 @@ input: /* empty */ $2); if (nasm_parser_temp_bc) nasm_parser_prev_bc = nasm_parser_temp_bc; - line_number++; + line_number += line_number_inc; } ; line: '\n' { $$ = (bytecode *)NULL; } | lineexp '\n' + | LINE INTNUM '+' INTNUM FILENAME '\n' { + line_number = intnum_get_uint($2); + line_number_inc = intnum_get_uint($4); + line_number -= line_number_inc; /* as we'll add it back in */ + switch_filename($5); + intnum_delete($2); + intnum_delete($4); + xfree($5); + $$ = (bytecode *)NULL; + } | directive '\n' { $$ = (bytecode *)NULL; } | error '\n' { Error(_("label or instruction expected at start of line")); diff --git a/src/parsers/nasm/token.l.in b/src/parsers/nasm/token.l.in index bcaf5aa9..d3524673 100644 --- a/src/parsers/nasm/token.l.in +++ b/src/parsers/nasm/token.l.in @@ -60,12 +60,14 @@ static size_t strbuf_size = 0; /* last "base" label for local (.) labels */ char *nasm_parser_locallabel_base = (char *)NULL; +static int linechg_numcount; + %} %option noyywrap %option nounput %option case-insensitive -%x DIRECTIVE +%x DIRECTIVE LINECHG LINECHG2 %s DIRECTIVE2 DIGIT [0-9] @@ -150,6 +152,27 @@ WS [ \t\r] return STRING; } + /* %line linenum+lineinc filename */ +^%line { BEGIN LINECHG; linechg_numcount = 0; return LINE; } +{DIGIT}+ { + linechg_numcount++; + yylval.intn = intnum_new_dec(yytext); + return INTNUM; +} +\n { BEGIN INITIAL; return '\n'; } +[+] { return yytext[0]; } +{WS}+ { + if (linechg_numcount == 2) + BEGIN LINECHG2; +} +\n { BEGIN INITIAL; return '\n'; } +\r ; +[^\r\n]+ { + BEGIN LINECHG; + yylval.str_val = xstrdup(yytext); + return FILENAME; +} + /* directive: [name value] */ ^{WS}*"[" { BEGIN DIRECTIVE; return '['; } "]" { BEGIN INITIAL; return ']'; } -- 2.40.0