Move Swig_locator from scanner.c to cscanner.c. Fix file and line error/warning reporting fixes where SWIG macros are used within {} braces (where the preprocessor expands macros), for example macros within %inline {...} and %fragment(...) {...} and nested structs. Basically anything that results ina call to skip_balanced() in the parser/preprocessor.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12227 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2010-09-24 22:13:13 +00:00
commit 31af118c41
7 changed files with 284 additions and 109 deletions

View file

@ -45,8 +45,6 @@ static int num_brace = 0;
static int last_brace = 0;
static int last_id = 0;
static int rename_active = 0;
static int expanding_macro = 0;
static int follow_locators = 0;
/* -----------------------------------------------------------------------------
* Swig_cparse_cplusplus()
@ -56,101 +54,6 @@ void Swig_cparse_cplusplus(int v) {
cparse_cplusplus = v;
}
/* ----------------------------------------------------------------------
* locator()
*
* Support for locator strings. These are strings of the form
* @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They
* are primarily used for macro line number reporting
* ---------------------------------------------------------------------- */
typedef struct Locator {
String *filename;
int line_number;
struct Locator *next;
} Locator;
static Locator *locs = 0;
/* we just use the locator to mark when active/deactive the linecounting */
static void scanner_locator(String *loc) {
if (!follow_locators) {
if (Equal(loc, "/*@SWIG@*/")) {
/* End locator. */
if (expanding_macro)
--expanding_macro;
} else {
/* Begin locator. */
++expanding_macro;
}
/* Freeze line number processing in Scanner */
Scanner_freeze_line(scan,expanding_macro);
} else {
int c;
Locator *l;
Seek(loc, 7, SEEK_SET);
c = Getc(loc);
if (c == '@') {
/* Empty locator. We pop the last location off */
if (locs) {
Scanner_set_location(scan,locs->filename,locs->line_number);
cparse_file = locs->filename;
cparse_line = locs->line_number;
l = locs->next;
free(locs);
locs = l;
}
return;
}
/* We're going to push a new location */
l = (Locator *) malloc(sizeof(Locator));
l->filename = cparse_file;
l->line_number = cparse_line;
l->next = locs;
locs = l;
/* Now, parse the new location out of the locator string */
{
String *fn = NewStringEmpty();
/* Putc(c, fn); */
while ((c = Getc(loc)) != EOF) {
if ((c == '@') || (c == ','))
break;
Putc(c, fn);
}
cparse_file = Swig_copy_string(Char(fn));
Clear(fn);
cparse_line = 1;
/* Get the line number */
while ((c = Getc(loc)) != EOF) {
if ((c == '@') || (c == ','))
break;
Putc(c, fn);
}
cparse_line = atoi(Char(fn));
Clear(fn);
/* Get the rest of it */
while ((c = Getc(loc)) != EOF) {
if (c == '@')
break;
Putc(c, fn);
}
/* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */
Scanner_set_location(scan,cparse_file,cparse_line);
Delete(fn);
}
}
}
void Swig_cparse_follow_locators(int v) {
follow_locators = v;
}
/* ----------------------------------------------------------------------------
* scanner_init()
*
@ -432,7 +335,7 @@ static int yylook(void) {
String *cmt = Scanner_text(scan);
char *loc = Char(cmt);
if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) {
scanner_locator(cmt);
Scanner_locator(scan, cmt);
}
}
break;

View file

@ -20,6 +20,7 @@ char cvsroot_scanner_c[] = "$Id$";
#include <ctype.h>
extern String *cparse_file;
extern int cparse_line;
extern int cparse_cplusplus;
extern int cparse_start_line;
@ -38,6 +39,13 @@ struct Scanner {
int freeze_line; /* Suspend line number updates */
};
typedef struct Locator {
String *filename;
int line_number;
struct Locator *next;
} Locator;
static int follow_locators = 0;
/* -----------------------------------------------------------------------------
* NewScanner()
*
@ -230,8 +238,7 @@ static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
* Returns error information (if any)
* ----------------------------------------------------------------------------- */
String *
Scanner_errmsg(Scanner *s) {
String *Scanner_errmsg(Scanner *s) {
return s->error;
}
@ -241,13 +248,12 @@ Scanner_errline(Scanner *s) {
}
/* -----------------------------------------------------------------------------
* Scanner_freeze_line()
* freeze_line()
*
* Freezes the current line number.
* ----------------------------------------------------------------------------- */
void
Scanner_freeze_line(Scanner *s, int val) {
static void freeze_line(Scanner *s, int val) {
s->freeze_line = val;
}
@ -1153,6 +1159,7 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
int l;
int state = 0;
char temp[2] = { 0, 0 };
String *locator = 0;
l = s->line;
temp[0] = (char) startchar;
Clear(s->text);
@ -1162,6 +1169,7 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
Append(s->text, temp);
while (num_levels > 0) {
if ((c = nextchar(s)) == 0) {
Delete(locator);
return -1;
}
switch (state) {
@ -1195,17 +1203,25 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
else
state = 11;
break;
case 12:
case 12: /* first character inside C comment */
if (c == '*')
state = 14;
else if (c == '@')
state = 40;
else
state = 13;
break;
case 13:
if (c == '*')
state = 13;
state = 14;
break;
case 14: /* possible end of C comment */
if (c == '*')
state = 14;
else if (c == '/')
state = 0;
else
state = 12;
state = 13;
break;
case 20:
if (c == '\"')
@ -1225,10 +1241,43 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
case 31:
state = 30;
break;
/* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */
case 40:
state = (c == 'S') ? 41 : (c == '*') ? 14 : 13;
break;
case 41:
state = (c == 'W') ? 42 : (c == '*') ? 14 : 13;
break;
case 42:
state = (c == 'I') ? 43 : (c == '*') ? 14 : 13;
break;
case 43:
state = (c == 'G') ? 44 : (c == '*') ? 14 : 13;
if (c == 'G') {
Delete(locator);
locator = NewString("/*@SWIG");
}
break;
case 44:
if (c == '*')
state = 45;
Putc(c, locator);
break;
case 45: /* end of SWIG locator in C comment */
if (c == '/') {
state = 0;
Putc(c, locator);
Scanner_locator(s, locator);
} else {
/* malformed locator */
state = (c == '*') ? 14 : 13;
}
break;
default:
break;
}
}
Delete(locator);
return 0;
}
@ -1239,8 +1288,98 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
* operator.
* ----------------------------------------------------------------------------- */
int
Scanner_isoperator(int tokval) {
int Scanner_isoperator(int tokval) {
if (tokval >= 100) return 1;
return 0;
}
/* ----------------------------------------------------------------------
* locator()
*
* Support for locator strings. These are strings of the form
* @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They
* are primarily used for macro line number reporting.
* We just use the locator to mark when to activate/deactivate linecounting.
* ---------------------------------------------------------------------- */
void Scanner_locator(Scanner *s, String *loc) {
static Locator *locs = 0;
static int expanding_macro = 0;
if (!follow_locators) {
if (Equal(loc, "/*@SWIG@*/")) {
/* End locator. */
if (expanding_macro)
--expanding_macro;
} else {
/* Begin locator. */
++expanding_macro;
}
/* Freeze line number processing in Scanner */
freeze_line(s,expanding_macro);
} else {
int c;
Locator *l;
Seek(loc, 7, SEEK_SET);
c = Getc(loc);
if (c == '@') {
/* Empty locator. We pop the last location off */
if (locs) {
Scanner_set_location(s, locs->filename, locs->line_number);
cparse_file = locs->filename;
cparse_line = locs->line_number;
l = locs->next;
free(locs);
locs = l;
}
return;
}
/* We're going to push a new location */
l = (Locator *) malloc(sizeof(Locator));
l->filename = cparse_file;
l->line_number = cparse_line;
l->next = locs;
locs = l;
/* Now, parse the new location out of the locator string */
{
String *fn = NewStringEmpty();
/* Putc(c, fn); */
while ((c = Getc(loc)) != EOF) {
if ((c == '@') || (c == ','))
break;
Putc(c, fn);
}
cparse_file = Swig_copy_string(Char(fn));
Clear(fn);
cparse_line = 1;
/* Get the line number */
while ((c = Getc(loc)) != EOF) {
if ((c == '@') || (c == ','))
break;
Putc(c, fn);
}
cparse_line = atoi(Char(fn));
Clear(fn);
/* Get the rest of it */
while ((c = Getc(loc)) != EOF) {
if (c == '@')
break;
Putc(c, fn);
}
/* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */
Scanner_set_location(s, cparse_file, cparse_line);
Delete(fn);
}
}
}
void Swig_cparse_follow_locators(int v) {
follow_locators = v;
}

View file

@ -30,7 +30,7 @@ extern void Scanner_idstart(Scanner *, const char *idchar);
extern String *Scanner_errmsg(Scanner *);
extern int Scanner_errline(Scanner *);
extern int Scanner_isoperator(int tokval);
extern void Scanner_freeze_line(Scanner *s, int val);
extern void Scanner_locator(Scanner *, String *loc);
/* Note: Tokens in range 100+ are for C/C++ operators */