Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Getting source file and line number of a function.
- X-seq: zsh-workers 25348
- From: "Rocky Bernstein" <rocky.bernstein@xxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: Getting source file and line number of a function.
- Date: Tue, 29 Jul 2008 22:31:13 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:in-reply-to:mime-version:content-type:references; bh=8r6+a2tzWr/6bw+bT/u69k6oB7dHQ9RI7IzMwhnQQxI=; b=LfMymfekDpItdWAjuGTXxoCNb6OLX6fV/zT51Tw4rETUewLN3YoIW+F/JC9kq72+M1 et/SDppiCm7UWoPMEOxkexORs+IOey2+F/rF6x82T0Y7IT3IrauBkzUrDINeft8LGBeP XBkRPtD81AAkGTwQ7f2AnijB6ElJOvsJ1iyWA=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version :content-type:references; b=jnRBZ1l5vgFuT2rpnuj2friU+6ATPoha3r+kPlEQj+W99QHCPZyUyIZm5L24v3JJsn IYEvm18vmnD0bkzBecMaLBxdayqs0j1u3xVDwEsTk3GM4EM6BMrAYeEXt1OCP9MB9Hg3 i/pLo9VLIPcuy678F189ihiVH4K5f6jl6qO64=
- In-reply-to: <6cd6de210807280546k14a1a59fo40cb6ed968b1227b@xxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <6cd6de210807261806r7ff184fdtcc7859cca0a98aef@xxxxxxxxxxxxxx> <200807280834.m6S8YEVo026326@xxxxxxxxxxxxxx> <6cd6de210807280546k14a1a59fo40cb6ed968b1227b@xxxxxxxxxxxxxx>
Attached is slight improvement on the patch posted before - it adds
source files to be put in functrace.
I'm not sure how functrace strings get freed; an explicit free() doesn't work
However see my next post regarding trap DEBUG.
On Mon, Jul 28, 2008 at 8:46 AM, Rocky Bernstein
<rocky.bernstein@xxxxxxxxx> wrote:
> Patch should be added. It's not the only way to do this and it changes
> the functrace (which could easily be addressed, so there might be some
> discussion.
>
> Comments about how the patch works are below. For the little that I've
> tried, it seems to work. Of course there are other line number
> weirdnesses I haven't worked out yet.
>
> One thing more easily addressed is the fact that sourcing a file
> doesn't show in functrace and I think it should. I think sourcing is
> in fact like a function call. In fact one can write "source" as a
> function which does a read/eval of the file name.
>
> In looking at the code in surrounding the patch one question I have is
> how the strings allocated for funcstack->name and funcstack->caller
> get freed? This is relevant if one extends source to do the same
> thing.
>
> Thanks.
>
>
> On Mon, Jul 28, 2008 at 4:34 AM, Peter Stephenson <pws@xxxxxxx> wrote:
>> "Rocky Bernstein" wrote:
>>> I see that zsh has now has array variables functrace and
>>> funcstack. Functrace stack gives a function name and a line offset
>>> from the function. But for many things involving location reporting,
>>> it would more be desirable to have a filename and absolute line
>>> location.
>>>
>>> Alternatively, if there were a way to get the filename and line number
>>> of the beginning of a given function, one can do some arithmetic to
>>> get the absolute position.
>>>
>>> Is there currently a way to get this information. Should I try at
>>> submitting a patch?
>>
>> It would be useful to have information referred to the autoload file,
>> and I've wondered about how to do it, but I don't think it's trivial
>> with the current way line numbers work. We would probably need to add
>> an extra internal variable for file line numbers, and present another
>> variable (or array, if in the funcstack style) to users to distinguish
>> the two.
>
> This is more or less the approach I tried. There is a variable called
> scriptname which I think is a little misleading. It is the name of the
> file when not in a function but gets set to a function name when that
> is run. So I added a variable called scriptfilename which mirrors
> scriptname but doesn't get changed when a function is run.
>
> When functions are defined, I save the current file, scriptfilename,
> and line number, lineno, in the shfunc structure. As for the C
> funcstack list, rather than remove any of the existing information, I
> added two more fields for the filename and absolute line number. Right
> now I changed the functrace routine in Src/Modules/parameter.c to use
> these new fields rather than the old ones. If one wants the function
> name rather than the file name, one can always use funcstack which has
> that. So right now you can't easily get the line number relative to
> the beginning of the function, although it's there.
>
> bash can show the new information, file name and starting line number using
>
> declare -F *fn*
>
> (Actually, shopt extdebug also has to be set.) It might be helpful to
> add that, and this would be one way to get the old function offset
> information. Another way would be to turn functrace into a builtin
> function and pass (an optional?) parameter indicating what flavor of
> information you want. Or a 3rd routine/variable could be used.
>
>>
>> --
>> Peter Stephenson <pws@xxxxxxx> Software Engineer
>> CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
>> Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070
>>
>
cvs diff -u
cvs diff: Diffing .
Index: exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.134
diff -u -r1.134 exec.c
--- exec.c 17 Jul 2008 11:27:57 -0000 1.134
+++ exec.c 30 Jul 2008 02:21:43 -0000
@@ -3913,6 +3913,8 @@
shf = (Shfunc) zalloc(sizeof(*shf));
shf->funcdef = prog;
shf->node.flags = 0;
+ shf->filename = ztrdup(scriptfilename);
+ shf->lineno = lineno;
if (!names) {
/*
@@ -4123,6 +4125,7 @@
#ifdef MAX_FUNCTION_DEPTH
static int funcdepth;
#endif
+ Shfunc shf;
pushheap();
@@ -4193,7 +4196,15 @@
fstack.lineno = lineno;
fstack.prev = funcstack;
funcstack = &fstack;
-
+ if (oargv0 && (shf = (Shfunc) shfunctab->getnode(shfunctab, oargv0))) {
+ fstack.flineno = shf->lineno + lineno;
+ fstack.filename = dupstring(shf->filename);
+ } else {
+ fstack.flineno = lineno;
+ fstack.filename = dupstring(fstack.caller);
+ }
+
+
if (prog->flags & EF_RUN) {
Shfunc shf;
Index: init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.86
diff -u -r1.86 init.c
--- init.c 17 Jul 2008 11:27:57 -0000 1.86
+++ init.c 30 Jul 2008 02:21:43 -0000
@@ -334,6 +334,7 @@
}
opts[INTERACTIVE] &= 1;
argzero = *argv;
+ scriptfilename = argzero;
argv++;
}
while (*argv)
@@ -1065,8 +1066,10 @@
int oldshst, osubsh, oloops;
FILE *obshin;
char *old_scriptname = scriptname, *us;
+ const char *old_scriptfilename = scriptfilename;
unsigned char *ocs;
int ocsp;
+ struct funcstack fstack;
if (!s ||
(!(prog = try_source_file((us = unmeta(s)))) &&
@@ -1096,8 +1099,17 @@
loops = 0;
dosetopt(SHINSTDIN, 0, 1);
scriptname = s;
+ scriptfilename = s;
sourcelevel++;
+ fstack.name = "source";
+ fstack.caller = dupstring(scriptname);
+ fstack.flineno = oldlineno;
+ fstack.lineno = oldlineno;
+ fstack.filename = dupstring(old_scriptfilename);
+ fstack.prev = funcstack;
+ funcstack = &fstack;
+
if (prog) {
pushheap();
errflag = 0;
@@ -1105,6 +1117,8 @@
popheap();
} else
loop(0, 0); /* loop through the file to be sourced */
+ funcstack = funcstack->prev;
+ scriptfilename = old_scriptfilename;
sourcelevel--;
/* restore the current shell state */
Index: utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.197
diff -u -r1.197 utils.c
--- utils.c 17 Jul 2008 11:27:57 -0000 1.197
+++ utils.c 30 Jul 2008 02:21:45 -0000
@@ -33,7 +33,8 @@
/* name of script being sourced */
/**/
-mod_export char *scriptname;
+mod_export char *scriptname; /* is sometimes a function name */
+mod_export char *scriptfilename;
#ifdef MULTIBYTE_SUPPORT
struct widechar_array {
Index: zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.138
diff -u -r1.138 zsh.h
--- zsh.h 12 Jun 2008 13:45:06 -0000 1.138
+++ zsh.h 30 Jul 2008 02:21:46 -0000
@@ -1059,6 +1059,8 @@
struct shfunc {
struct hashnode node;
+ char *filename; /* Name of file located in */
+ int lineno; /* line number in above file */
Eprog funcdef; /* function definition */
};
@@ -1077,8 +1079,10 @@
struct funcstack {
Funcstack prev; /* previous in stack */
char *name; /* name of function called */
+ char *filename; /* file function resides in */
char *caller; /* name of caller */
- int lineno; /* line number in file */
+ int flineno; /* line number in file */
+ int lineno; /* line offset from beginning of function */
};
/* node in list of function call wrappers */
cvs diff: Diffing Builtins
cvs diff: Diffing Modules
Index: Modules/parameter.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v
retrieving revision 1.45
diff -u -r1.45 parameter.c
--- Modules/parameter.c 5 Sep 2007 16:16:17 -0000 1.45
+++ Modules/parameter.c 30 Jul 2008 02:21:46 -0000
@@ -528,8 +528,8 @@
for (f = funcstack, p = ret; f; f = f->prev, p++) {
char *colonpair;
- colonpair = zhalloc(strlen(f->caller) + (f->lineno > 9999 ? 24 : 6));
- sprintf(colonpair, "%s:%d", f->caller, f->lineno);
+ colonpair = zhalloc(strlen(f->filename) + (f->flineno > 9999 ? 24 : 6));
+ sprintf(colonpair, "%s:%d", f->filename, f->flineno);
*p = colonpair;
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author