diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-12 16:49:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-12 16:49:18 -0300 |
commit | 8714cc02d6367039d3d76279f024d30326371277 (patch) | |
tree | ea60817bdf1507fe44678f2363ed15e35194119e | |
parent | 69b45bb4e9b08469e9fe2148d0aebf49ec54c6d2 (diff) | |
download | lua-8714cc02d6367039d3d76279f024d30326371277.tar.gz lua-8714cc02d6367039d3d76279f024d30326371277.tar.bz2 lua-8714cc02d6367039d3d76279f024d30326371277.zip |
`getinfo' gets information about non-active functions, too.
-rw-r--r-- | ldblib.c | 78 | ||||
-rw-r--r-- | ldebug.c | 18 | ||||
-rw-r--r-- | manual.tex | 50 |
3 files changed, 91 insertions, 55 deletions
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.13 2000/04/14 17:44:20 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.14 2000/05/08 13:21:35 roberto Exp roberto $ |
3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <stdio.h> | ||
8 | #include <stdlib.h> | 9 | #include <stdlib.h> |
9 | #include <string.h> | 10 | #include <string.h> |
10 | 11 | ||
@@ -41,40 +42,51 @@ static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) { | |||
41 | } | 42 | } |
42 | 43 | ||
43 | 44 | ||
44 | static void getstack (lua_State *L) { | 45 | static void getinfo (lua_State *L) { |
45 | lua_Debug ar; | 46 | lua_Debug ar; |
46 | if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ | 47 | lua_Object res; |
47 | return; | 48 | lua_Object func = lua_getparam(L, 1); |
48 | else { | 49 | const char *options = luaL_opt_string(L, 2, "flnSu"); |
49 | const char *options = luaL_opt_string(L, 2, "flnSu"); | 50 | char buff[20]; |
50 | lua_Object res = lua_createtable(L); | 51 | if (lua_isnumber(L, func)) { |
51 | if (!lua_getinfo(L, options, &ar)) | 52 | if (!lua_getstack(L, lua_getnumber(L, func), &ar)) { |
52 | luaL_argerror(L, 2, "invalid option"); | 53 | lua_pushnil(L); /* level out of range */ |
53 | for (; *options; options++) { | 54 | return; |
54 | switch (*options) { | 55 | } |
55 | case 'S': | 56 | } |
56 | settabss(L, res, "source", ar.source); | 57 | else if (lua_isfunction(L, func)) { |
57 | settabsi(L, res, "linedefined", ar.linedefined); | 58 | ar.func = func; |
58 | settabss(L, res, "what", ar.what); | 59 | sprintf(buff, ">%.10s", options); |
59 | break; | 60 | options = buff; |
60 | case 'l': | 61 | } |
61 | settabsi(L, res, "currentline", ar.currentline); | 62 | else |
62 | break; | 63 | luaL_argerror(L, 1, "function or level expected"); |
63 | case 'u': | 64 | res = lua_createtable(L); |
64 | settabsi(L, res, "nups", ar.nups); | 65 | if (!lua_getinfo(L, options, &ar)) |
65 | break; | 66 | luaL_argerror(L, 2, "invalid option"); |
66 | case 'n': | 67 | for (; *options; options++) { |
67 | settabss(L, res, "name", ar.name); | 68 | switch (*options) { |
68 | settabss(L, res, "namewhat", ar.namewhat); | 69 | case 'S': |
69 | break; | 70 | settabss(L, res, "source", ar.source); |
70 | case 'f': | 71 | settabsi(L, res, "linedefined", ar.linedefined); |
71 | settabso(L, res, "func", ar.func); | 72 | settabss(L, res, "what", ar.what); |
72 | break; | 73 | break; |
73 | 74 | case 'l': | |
74 | } | 75 | settabsi(L, res, "currentline", ar.currentline); |
76 | break; | ||
77 | case 'u': | ||
78 | settabsi(L, res, "nups", ar.nups); | ||
79 | break; | ||
80 | case 'n': | ||
81 | settabss(L, res, "name", ar.name); | ||
82 | settabss(L, res, "namewhat", ar.namewhat); | ||
83 | break; | ||
84 | case 'f': | ||
85 | settabso(L, res, "func", ar.func); | ||
86 | break; | ||
75 | } | 87 | } |
76 | lua_pushobject(L, res); | ||
77 | } | 88 | } |
89 | lua_pushobject(L, res); | ||
78 | } | 90 | } |
79 | 91 | ||
80 | 92 | ||
@@ -163,7 +175,7 @@ static void setlinehook (lua_State *L) { | |||
163 | 175 | ||
164 | static const struct luaL_reg dblib[] = { | 176 | static const struct luaL_reg dblib[] = { |
165 | {"getlocal", getlocal}, | 177 | {"getlocal", getlocal}, |
166 | {"getstack", getstack}, | 178 | {"getinfo", getinfo}, |
167 | {"setcallhook", setcallhook}, | 179 | {"setcallhook", setcallhook}, |
168 | {"setlinehook", setlinehook}, | 180 | {"setlinehook", setlinehook}, |
169 | {"setlocal", setlocal} | 181 | {"setlocal", setlocal} |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.17 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -132,8 +132,7 @@ int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { | |||
132 | } | 132 | } |
133 | 133 | ||
134 | 134 | ||
135 | static void lua_funcinfo (lua_Debug *ar) { | 135 | static void lua_funcinfo (lua_Debug *ar, StkId func) { |
136 | StkId func = ar->_func; | ||
137 | switch (ttype(func)) { | 136 | switch (ttype(func)) { |
138 | case TAG_LCLOSURE: case TAG_LMARK: | 137 | case TAG_LCLOSURE: case TAG_LMARK: |
139 | ar->source = clvalue(func)->f.l->source->str; | 138 | ar->source = clvalue(func)->f.l->source->str; |
@@ -164,7 +163,7 @@ static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { | |||
164 | /* try to find a name for given function */ | 163 | /* try to find a name for given function */ |
165 | setnormalized(L->top, f); /* to be used by `checkfunc' */ | 164 | setnormalized(L->top, f); /* to be used by `checkfunc' */ |
166 | for (i=0; i<=g->size; i++) { | 165 | for (i=0; i<=g->size; i++) { |
167 | if (checkfunc(L, val(node(g,i))) && ttype(key(node(g,i))) == TAG_STRING) { | 166 | if (ttype(key(node(g,i))) == TAG_STRING && checkfunc(L, val(node(g,i)))) { |
168 | ar->name = tsvalue(key(node(g,i)))->str; | 167 | ar->name = tsvalue(key(node(g,i)))->str; |
169 | ar->namewhat = "global"; | 168 | ar->namewhat = "global"; |
170 | return; | 169 | return; |
@@ -178,12 +177,17 @@ static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { | |||
178 | 177 | ||
179 | 178 | ||
180 | int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | 179 | int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
181 | StkId func = ar->_func; | 180 | StkId func; |
182 | LUA_ASSERT(L, is_T_MARK(ttype(func)), "invalid activation record"); | 181 | if (*what != '>') |
182 | func = ar->_func; | ||
183 | else { | ||
184 | what++; /* skip the '>' */ | ||
185 | func = ar->func; | ||
186 | } | ||
183 | for (; *what; what++) { | 187 | for (; *what; what++) { |
184 | switch (*what) { | 188 | switch (*what) { |
185 | case 'S': | 189 | case 'S': |
186 | lua_funcinfo(ar); | 190 | lua_funcinfo(ar, func); |
187 | break; | 191 | break; |
188 | case 'l': | 192 | case 'l': |
189 | ar->currentline = lua_currentline(L, func); | 193 | ar->currentline = lua_currentline(L, func); |
@@ -1,4 +1,4 @@ | |||
1 | % $Id: manual.tex,v 1.36 2000/04/17 19:23:48 roberto Exp roberto $ | 1 | % $Id: manual.tex,v 1.37 2000/05/12 19:19:18 roberto Exp roberto $ |
2 | 2 | ||
3 | \documentclass[11pt]{article} | 3 | \documentclass[11pt]{article} |
4 | \usepackage{fullpage,bnf} | 4 | \usepackage{fullpage,bnf} |
@@ -122,7 +122,7 @@ Waldemar Celes | |||
122 | \tecgraf\ --- Computer Science Department --- PUC-Rio | 122 | \tecgraf\ --- Computer Science Department --- PUC-Rio |
123 | } | 123 | } |
124 | 124 | ||
125 | \date{{\small \tt\$Date: 2000/04/17 19:23:48 $ $}} | 125 | \date{{\small \tt\$Date: 2000/05/12 19:19:18 $ $}} |
126 | 126 | ||
127 | \maketitle | 127 | \maketitle |
128 | 128 | ||
@@ -3329,7 +3329,22 @@ selects some fields of \verb|ar| to be filled, | |||
3329 | as indicated by the letter in parentheses in the definition of \verb|lua_Debug|; | 3329 | as indicated by the letter in parentheses in the definition of \verb|lua_Debug|; |
3330 | that is, an \verb|S| fills the fields \verb|source| and \verb|linedefined|, | 3330 | that is, an \verb|S| fills the fields \verb|source| and \verb|linedefined|, |
3331 | and \verb|l| fills the field \verb|currentline|, etc. | 3331 | and \verb|l| fills the field \verb|currentline|, etc. |
3332 | We describe each field below: | 3332 | |
3333 | To get information about a function that is not active (that is, | ||
3334 | it is not in the stack), | ||
3335 | you set the \verb|func| field of the \verb|lua_Debug| structure | ||
3336 | with the function, | ||
3337 | and start the \verb|what| string with the character \verb|>|. | ||
3338 | For instance, to know in which line a function \verb|f| was defined, | ||
3339 | you can write | ||
3340 | \begin{verbatim} | ||
3341 | lua_Debug ar; | ||
3342 | ar.func = lua_getglobal(L, "f"); | ||
3343 | lua_getinfo(L, ">S", &ar); | ||
3344 | printf("%d\n", ar.linedefined); | ||
3345 | \end{verbatim} | ||
3346 | |||
3347 | The fields of \verb|lua_Debug| have the following meaning: | ||
3333 | \begin{description} | 3348 | \begin{description} |
3334 | 3349 | ||
3335 | \item[source] | 3350 | \item[source] |
@@ -3523,21 +3538,26 @@ As a general rule, if your program does not need this library, | |||
3523 | do not open it. | 3538 | do not open it. |
3524 | 3539 | ||
3525 | 3540 | ||
3526 | \subsubsection*{\ff \T{getstack (level, [what])}}\Deffunc{getstack} | 3541 | \subsubsection*{\ff \T{getinfo (function, [what])}}\Deffunc{getinfo} |
3542 | |||
3543 | This function returns a table with information about a function. | ||
3544 | You can give the function directly, | ||
3545 | or you can give a number as the value of \verb|function|, | ||
3546 | which means the function running at level \verb|function| of the stack: | ||
3547 | Level 0 is the current function (\verb|getinfo| itself); | ||
3548 | level 1 is the function that called \verb|getinfo|; | ||
3549 | and so on. | ||
3550 | If \verb|function| is a number larger than the number of active functions, | ||
3551 | \verb|getinfo| returns \nil. | ||
3527 | 3552 | ||
3528 | This function returns a table with information about the function | 3553 | The returned table contains all the fields returned by \verb|lua_getinfo|, |
3529 | running at level \verb|level| of the stack. | ||
3530 | Level 0 is the current function (\verb|getstack| itself); | ||
3531 | level 1 is the function that called \verb|getstack|. | ||
3532 | If \verb|level| is larger than the number of active functions, | ||
3533 | the function returns \nil. | ||
3534 | The table contains all the fields returned by \verb|lua_getinfo|, | ||
3535 | with the string \verb|what| describing what to get. | 3554 | with the string \verb|what| describing what to get. |
3536 | The default for \rerb|what| is to get all information available. | 3555 | The default for \verb|what| is to get all information available. |
3537 | 3556 | ||
3538 | For instance, the expression \verb|getstack(1,"n").name| returns | 3557 | For instance, the expression \verb|getinfo(1,"n").name| returns |
3539 | the name of the current function, | 3558 | the name of the current function, if a reasonable name can be found, |
3540 | if a reasonable name can be found. | 3559 | and \verb|getinfo(print)| returns a table with all available information |
3560 | about the \verb|print| function. | ||
3541 | 3561 | ||
3542 | 3562 | ||
3543 | \subsubsection*{\ff \T{getlocal (level, local)}}\Deffunc{getlocal} | 3563 | \subsubsection*{\ff \T{getlocal (level, local)}}\Deffunc{getlocal} |