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:
parent
ea9275ca08
commit
31af118c41
7 changed files with 284 additions and 109 deletions
|
|
@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 2.0.1 (in progress)
|
Version 2.0.1 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2010-09-24: wsfulton
|
||||||
|
More 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.
|
||||||
|
|
||||||
2010-09-18: wsfulton
|
2010-09-18: wsfulton
|
||||||
More file and line error/warning reporting fixes for various inherited
|
More file and line error/warning reporting fixes for various inherited
|
||||||
class problems.
|
class problems.
|
||||||
|
|
|
||||||
103
Examples/test-suite/errors/cpp_macro_locator.i
Normal file
103
Examples/test-suite/errors/cpp_macro_locator.i
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
%module xxx
|
||||||
|
|
||||||
|
// Test the SWIG preprocessor locator effects on reporting line numbers in warnings when processing SWIG (multiline) macros
|
||||||
|
|
||||||
|
// The ignored overloaded methods warnings should have the correct line number reporting
|
||||||
|
// {} blocks are tested, where the preprocessor expands the macros
|
||||||
|
|
||||||
|
%define CLASSMACRO(KLASS)
|
||||||
|
class KLASS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KLASS() {}
|
||||||
|
void methodX(int *) {}
|
||||||
|
void methodX(const int *) {}
|
||||||
|
};
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
%{
|
||||||
|
#define CLASSMACRO(KLASS) \
|
||||||
|
class KLASS \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
KLASS() {} \
|
||||||
|
void methodX(int *) {} \
|
||||||
|
void methodX(const int *) {} \
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#define VARIABLEMACRO(NAME) double NAME;
|
||||||
|
struct Outer {
|
||||||
|
struct Inner {
|
||||||
|
VARIABLEMACRO(MyInnerVar)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
void overload1(int *) {}
|
||||||
|
void overload1(const int *) {}
|
||||||
|
void overload2(int *) {}
|
||||||
|
void overload2(const int *) {}
|
||||||
|
void overload3(int *) {}
|
||||||
|
void overload3(const int *) {}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%define VARIABLEMACRO(NAME)
|
||||||
|
double NAME;
|
||||||
|
%enddef
|
||||||
|
struct Outer {
|
||||||
|
struct Inner {
|
||||||
|
VARIABLEMACRO(MyInnerVar)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
void overload1(int *) {}
|
||||||
|
void overload1(const int *) {}
|
||||||
|
|
||||||
|
%fragment("FragmentMethod", "header") {
|
||||||
|
void fragmentMethod() {
|
||||||
|
}
|
||||||
|
VARIABLEMACRO(fragVar)
|
||||||
|
}
|
||||||
|
void overload2(int *) {}
|
||||||
|
void overload2(const int *) {}
|
||||||
|
|
||||||
|
%inline {
|
||||||
|
CLASSMACRO(Klass1)
|
||||||
|
}
|
||||||
|
#warning inline warning message one
|
||||||
|
void overload3(int *) {}
|
||||||
|
void overload3(const int *) {}
|
||||||
|
|
||||||
|
%{
|
||||||
|
struct Classic {
|
||||||
|
Classic() {
|
||||||
|
VARIABLEMACRO(inconstructor)
|
||||||
|
}
|
||||||
|
double value;
|
||||||
|
};
|
||||||
|
void overload4(int *) {}
|
||||||
|
void overload4(const int *) {}
|
||||||
|
void overload5(int *) {}
|
||||||
|
void overload5(const int *) {}
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct Classic {
|
||||||
|
Classic() {
|
||||||
|
VARIABLEMACRO(inconstructor)
|
||||||
|
}
|
||||||
|
double value;
|
||||||
|
};
|
||||||
|
void overload4(int *) {}
|
||||||
|
void overload4(const int *) {}
|
||||||
|
|
||||||
|
%inline {
|
||||||
|
void overloadinline1(int *) {}
|
||||||
|
void overloadinline1(const int *) {}
|
||||||
|
CLASSMACRO(Klass2)
|
||||||
|
#warning an inline warning message 2
|
||||||
|
void overloadinline2(int *) {}
|
||||||
|
void overloadinline2(const int *) {}
|
||||||
|
}
|
||||||
|
void overload5(int *) {}
|
||||||
|
void overload5(const int *) {}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -225,6 +225,29 @@ cpp_inherit.i:26: Warning 401: Nothing known about base class 'A7< int >'. Ignor
|
||||||
cpp_inherit.i:26: Warning 401: Maybe you forgot to instantiate 'A7< int >' using %template.
|
cpp_inherit.i:26: Warning 401: Maybe you forgot to instantiate 'A7< int >' using %template.
|
||||||
cpp_inherit.i:45: Warning 323: Recursive scope inheritance of 'Recursive'.
|
cpp_inherit.i:45: Warning 323: Recursive scope inheritance of 'Recursive'.
|
||||||
|
|
||||||
|
:::::::::::::::::::::::::::::::: cpp_macro_locator.i :::::::::::::::::::::::::::::::::::
|
||||||
|
cpp_macro_locator.i:66: Warning 204: CPP #warning, inline warning message one
|
||||||
|
cpp_macro_locator.i:96: Warning 204: CPP #warning, an inline warning message 2
|
||||||
|
cpp_macro_locator.i:50: Warning 325: Nested struct not currently supported (Inner ignored)
|
||||||
|
cpp_macro_locator.i:53: Warning 509: Overloaded method overload1(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:52: Warning 509: as it is shadowed by overload1(int *).
|
||||||
|
cpp_macro_locator.i:61: Warning 509: Overloaded method overload2(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:60: Warning 509: as it is shadowed by overload2(int *).
|
||||||
|
cpp_macro_locator.i:64: Warning 509: Overloaded method Klass1::methodX(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:64: Warning 509: as it is shadowed by Klass1::methodX(int *).
|
||||||
|
cpp_macro_locator.i:68: Warning 509: Overloaded method overload3(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:67: Warning 509: as it is shadowed by overload3(int *).
|
||||||
|
cpp_macro_locator.i:90: Warning 509: Overloaded method overload4(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:89: Warning 509: as it is shadowed by overload4(int *).
|
||||||
|
cpp_macro_locator.i:94: Warning 509: Overloaded method overloadinline1(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:93: Warning 509: as it is shadowed by overloadinline1(int *).
|
||||||
|
cpp_macro_locator.i:95: Warning 509: Overloaded method Klass2::methodX(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:95: Warning 509: as it is shadowed by Klass2::methodX(int *).
|
||||||
|
cpp_macro_locator.i:98: Warning 509: Overloaded method overloadinline2(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:97: Warning 509: as it is shadowed by overloadinline2(int *).
|
||||||
|
cpp_macro_locator.i:101: Warning 509: Overloaded method overload5(int const *) effectively ignored,
|
||||||
|
cpp_macro_locator.i:100: Warning 509: as it is shadowed by overload5(int *).
|
||||||
|
|
||||||
:::::::::::::::::::::::::::::::: cpp_missing_rtemplate.i :::::::::::::::::::::::::::::::::::
|
:::::::::::::::::::::::::::::::: cpp_missing_rtemplate.i :::::::::::::::::::::::::::::::::::
|
||||||
cpp_missing_rtemplate.i:4: Error: Syntax error in input(1).
|
cpp_missing_rtemplate.i:4: Error: Syntax error in input(1).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ cpp_extend_redefine
|
||||||
cpp_extend_undefined
|
cpp_extend_undefined
|
||||||
cpp_inline_namespace
|
cpp_inline_namespace
|
||||||
cpp_inherit
|
cpp_inherit
|
||||||
|
cpp_macro_locator
|
||||||
cpp_missing_rtemplate
|
cpp_missing_rtemplate
|
||||||
cpp_namespace_alias
|
cpp_namespace_alias
|
||||||
cpp_namespace_aliasnot
|
cpp_namespace_aliasnot
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,6 @@ static int num_brace = 0;
|
||||||
static int last_brace = 0;
|
static int last_brace = 0;
|
||||||
static int last_id = 0;
|
static int last_id = 0;
|
||||||
static int rename_active = 0;
|
static int rename_active = 0;
|
||||||
static int expanding_macro = 0;
|
|
||||||
static int follow_locators = 0;
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_cparse_cplusplus()
|
* Swig_cparse_cplusplus()
|
||||||
|
|
@ -56,101 +54,6 @@ void Swig_cparse_cplusplus(int v) {
|
||||||
cparse_cplusplus = 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()
|
* scanner_init()
|
||||||
*
|
*
|
||||||
|
|
@ -432,7 +335,7 @@ static int yylook(void) {
|
||||||
String *cmt = Scanner_text(scan);
|
String *cmt = Scanner_text(scan);
|
||||||
char *loc = Char(cmt);
|
char *loc = Char(cmt);
|
||||||
if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) {
|
if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) {
|
||||||
scanner_locator(cmt);
|
Scanner_locator(scan, cmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ char cvsroot_scanner_c[] = "$Id$";
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
extern String *cparse_file;
|
extern String *cparse_file;
|
||||||
|
extern int cparse_line;
|
||||||
extern int cparse_cplusplus;
|
extern int cparse_cplusplus;
|
||||||
extern int cparse_start_line;
|
extern int cparse_start_line;
|
||||||
|
|
||||||
|
|
@ -38,6 +39,13 @@ struct Scanner {
|
||||||
int freeze_line; /* Suspend line number updates */
|
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()
|
* NewScanner()
|
||||||
*
|
*
|
||||||
|
|
@ -230,8 +238,7 @@ static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
|
||||||
* Returns error information (if any)
|
* Returns error information (if any)
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
String *
|
String *Scanner_errmsg(Scanner *s) {
|
||||||
Scanner_errmsg(Scanner *s) {
|
|
||||||
return s->error;
|
return s->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,13 +248,12 @@ Scanner_errline(Scanner *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Scanner_freeze_line()
|
* freeze_line()
|
||||||
*
|
*
|
||||||
* Freezes the current line number.
|
* Freezes the current line number.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void
|
static void freeze_line(Scanner *s, int val) {
|
||||||
Scanner_freeze_line(Scanner *s, int val) {
|
|
||||||
s->freeze_line = val;
|
s->freeze_line = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1153,6 +1159,7 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
||||||
int l;
|
int l;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
char temp[2] = { 0, 0 };
|
char temp[2] = { 0, 0 };
|
||||||
|
String *locator = 0;
|
||||||
l = s->line;
|
l = s->line;
|
||||||
temp[0] = (char) startchar;
|
temp[0] = (char) startchar;
|
||||||
Clear(s->text);
|
Clear(s->text);
|
||||||
|
|
@ -1162,6 +1169,7 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
||||||
Append(s->text, temp);
|
Append(s->text, temp);
|
||||||
while (num_levels > 0) {
|
while (num_levels > 0) {
|
||||||
if ((c = nextchar(s)) == 0) {
|
if ((c = nextchar(s)) == 0) {
|
||||||
|
Delete(locator);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
@ -1195,17 +1203,25 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
||||||
else
|
else
|
||||||
state = 11;
|
state = 11;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12: /* first character inside C comment */
|
||||||
if (c == '*')
|
if (c == '*')
|
||||||
|
state = 14;
|
||||||
|
else if (c == '@')
|
||||||
|
state = 40;
|
||||||
|
else
|
||||||
state = 13;
|
state = 13;
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
if (c == '*')
|
if (c == '*')
|
||||||
state = 13;
|
state = 14;
|
||||||
|
break;
|
||||||
|
case 14: /* possible end of C comment */
|
||||||
|
if (c == '*')
|
||||||
|
state = 14;
|
||||||
else if (c == '/')
|
else if (c == '/')
|
||||||
state = 0;
|
state = 0;
|
||||||
else
|
else
|
||||||
state = 12;
|
state = 13;
|
||||||
break;
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
if (c == '\"')
|
if (c == '\"')
|
||||||
|
|
@ -1225,10 +1241,43 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
||||||
case 31:
|
case 31:
|
||||||
state = 30;
|
state = 30;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Delete(locator);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1239,8 +1288,98 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
|
||||||
* operator.
|
* operator.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int Scanner_isoperator(int tokval) {
|
||||||
Scanner_isoperator(int tokval) {
|
|
||||||
if (tokval >= 100) return 1;
|
if (tokval >= 100) return 1;
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ extern void Scanner_idstart(Scanner *, const char *idchar);
|
||||||
extern String *Scanner_errmsg(Scanner *);
|
extern String *Scanner_errmsg(Scanner *);
|
||||||
extern int Scanner_errline(Scanner *);
|
extern int Scanner_errline(Scanner *);
|
||||||
extern int Scanner_isoperator(int tokval);
|
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 */
|
/* Note: Tokens in range 100+ are for C/C++ operators */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue