lineno on failed compile() commands...

lance@markv.com
Thu, 16 Sep 93 15:38:21 PDT

Well I looked around the code and saw that there was a way to
extract the linenumber that the builtin.compile() command
was on when it fails.. But only from the C code and only
down inside the parser instead of the compiler...

I decided I would hack the code up a little so that if builtin.compile()
failed, it would create an attribute called sys.failed_lineno that could
be looked at that comtains JUST the line number. This is not the cleanest
but will allow me to continue...
I would use it like this:

try:
co = compile(a,'<string>','exec')
except SyntaxError, msg:
print 'SyntaxError: ' + msg + ' on line #' + `sys.lineno`

if anyone has a better idea or way to do it, please let me know...
Here are the diffs to allow this..
===================================================================
RCS file: /u/lance/CVS/python/src/parsetok.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 parsetok.c
*** 1.1.1.1 1993/09/09 20:58:43
--- parsetok.c 1993/09/16 20:19:17
***************
*** 40,50 ****
/* Parse input coming from a string. Return error code, print some errors. */

int
! parsestring(s, g, start, n_ret)
char *s;
grammar *g;
int start;
node **n_ret;
{
struct tok_state *tok = tok_setups(s);
int ret;
--- 40,51 ----
/* Parse input coming from a string. Return error code, print some errors. */

int
! parsestring(s, g, start, n_ret, lineno)
char *s;
grammar *g;
int start;
node **n_ret;
+ int *lineno;
{
struct tok_state *tok = tok_setups(s);
int ret;
***************
*** 54,59 ****
--- 55,65 ----
return E_NOMEM;
}
ret = parsetok(tok, g, start, n_ret);
+ if (ret == E_TOKEN || ret == E_SYNTAX) {
+ if (lineno) {
+ *lineno = tok->lineno;
+ }
+ }
/*
XXX Need a more sophisticated way to report the line number.
if (ret == E_TOKEN || ret == E_SYNTAX) {
===================================================================
RCS file: /u/lance/CVS/python/src/parsetok.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 parsetok.h
*** 1.1.1.1 1993/09/09 20:58:43
--- parsetok.h 1993/09/16 20:19:18
***************
*** 30,36 ****

/* Parser-tokenizer link interface */

! extern int parsestring PROTO((char *, grammar *, int start, node **n_ret));
extern int parsefile PROTO((FILE *, char *, grammar *, int start,
char *ps1, char *ps2, node **n_ret));

--- 30,36 ----

/* Parser-tokenizer link interface */

! extern int parsestring PROTO((char *, grammar *, int start, node **n_ret, int *lineno));
extern int parsefile PROTO((FILE *, char *, grammar *, int start,
char *ps1, char *ps2, node **n_ret));

===================================================================
RCS file: /u/lance/CVS/python/src/pythonrun.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 pythonrun.c
*** 1.1.1.1 1993/09/09 20:57:38
--- pythonrun.c 1993/09/16 22:10:05
***************
*** 267,273 ****
{
node *n;
int err;
! err = parse_string(str, start, &n);
return run_err_node(err, n, "<string>", globals, locals);
}

--- 267,273 ----
{
node *n;
int err;
! err = parse_string(str, start, &n, 0);
return run_err_node(err, n, "<string>", globals, locals);
}

***************
*** 334,342 ****
node *n;
int err;
codeobject *co;
! err = parse_string(str, start, &n);
if (err != E_DONE) {
err_input(err);
return NULL;
}
co = compile(n, filename);
--- 334,347 ----
node *n;
int err;
codeobject *co;
! int lineno; /* If error, this holds line number of failure */
! /* make sure "failed_lineno" does not exist incase things work ok */
! sysset("failed_lineno",NULL);
! err = parse_string(str, start, &n, &lineno);
if (err != E_DONE) {
err_input(err);
+ /* Set "failed_lineno" so you can capture line of failure */
+ sysset("failed_lineno",newintobject(lineno));
return NULL;
}
co = compile(n, filename);
***************
*** 364,375 ****
/* Simplified interface to parsestring */

int
! parse_string(str, start, n_ret)
char *str;
int start;
node **n_ret;
{
! int err = parsestring(str, &gram, start, n_ret);
/* Don't confuse early end of string with early end of input */
if (err == E_EOF)
err = E_SYNTAX;
--- 369,381 ----
/* Simplified interface to parsestring */

int
! parse_string(str, start, n_ret, lineno)
char *str;
int start;
node **n_ret;
+ int *lineno;
{
! int err = parsestring(str, &gram, start, n_ret, lineno);
/* Don't confuse early end of string with early end of input */
if (err == E_EOF)
err = E_SYNTAX;
===================================================================
RCS file: /u/lance/CVS/python/src/pythonrun.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 pythonrun.h
*** 1.1.1.1 1993/09/09 20:58:42
--- pythonrun.h 1993/09/16 20:19:19
***************
*** 39,45 ****
int run_tty_1 PROTO((FILE *, char *));
int run_tty_loop PROTO((FILE *, char *));

! int parse_string PROTO((char *, int, struct _node **));
int parse_file PROTO((FILE *, char *, int, struct _node **));

object *eval_node PROTO((struct _node *, char *, object *, object *));
--- 39,45 ----
int run_tty_1 PROTO((FILE *, char *));
int run_tty_loop PROTO((FILE *, char *));

! int parse_string PROTO((char *, int, struct _node **, int *));
int parse_file PROTO((FILE *, char *, int, struct _node **));

object *eval_node PROTO((struct _node *, char *, object *, object *));

--

Lance Ellinghouse lance@markv.com

1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com`