diff --git a/lib/master.pike.in b/lib/master.pike.in index bd3e649859ea519b025ab05ef3c757f130365a51..bdfd5466d0ba69ef280ef55233472965d061bc0e 100644 --- a/lib/master.pike.in +++ b/lib/master.pike.in @@ -6,7 +6,7 @@ // Pike is distributed under GPL, LGPL and MPL. See the file COPYING // for more information. // -// $Id: master.pike.in,v 1.262 2003/03/20 18:00:36 mast Exp $ +// $Id: master.pike.in,v 1.263 2003/03/27 02:32:04 mast Exp $ #pike __REAL_VERSION__ @@ -71,6 +71,37 @@ int compat_minor=-1; #define capitalize(X) (upper_case((X)[..0])+(X)[1..]) #define write(X) _static_modules.files()->_stdout->write(X) +#ifdef RESOLV_DEBUG + +#if constant (thread_local) +static object resolv_msg_depth = thread_local(); +#define GET_RESOLV_MSG_DEPTH (resolv_msg_depth->get()) +#define INC_RESOLV_MSG_DEPTH() (resolv_msg_depth->set (resolv_msg_depth->get() + 1)) +#define DEC_RESOLV_MSG_DEPTH() (resolv_msg_depth->set (resolv_msg_depth->get() - 1)) +#else +static int resolv_msg_depth; +#define GET_RESOLV_MSG_DEPTH resolv_msg_depth +#define INC_RESOLV_MSG_DEPTH() (++resolv_msg_depth) +#define DEC_RESOLV_MSG_DEPTH() (--resolv_msg_depth) +#endif + +void resolv_debug (string fmt, mixed... args) +{ + string pad = " " * GET_RESOLV_MSG_DEPTH; + if (sizeof (args)) fmt = sprintf (fmt, @args); + if (fmt[-1] == '\n') + fmt = pad + replace (fmt[..sizeof (fmt) - 2], "\n", "\n" + pad) + "\n"; + else + fmt = pad + replace (fmt, "\n", "\n" + pad); + werror (fmt); +} + +#else // !RESOLV_DEBUG +#define INC_RESOLV_MSG_DEPTH() 0 +#define DEC_RESOLV_MSG_DEPTH() 0 +#define resolv_debug(X...) do {} while (0) +#endif // !RESOLV_DEBUG + //! @appears error //! Throws an error. A more readable version of the code //! @tt{throw( ({ sprintf(f, @@args), backtrace() }) )@}. @@ -530,10 +561,7 @@ static program low_findprog(string pname, #endif { if(!zero_type (ret=programs[fname])) { -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s returning cached (no autoreload)\n" - " %O\n", fname, ret); -#endif + resolv_debug ("low_findprog %s: returning cached (no autoreload)\n", fname); return ret; } } @@ -560,9 +588,7 @@ static program low_findprog(string pname, #ifdef PIKE_AUTORELOAD if (load_time[fname] > s[3]) if (!zero_type (ret=programs[fname])) { -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s returning cached (autoreload)\n", fname); -#endif + resolv_debug ("low_findprog %s: returning cached (autoreload)\n", fname); return ret; } #endif @@ -578,15 +604,18 @@ static program low_findprog(string pname, { mixed err=catch { AUTORELOAD_CHECK_FILE(oname); + resolv_debug ("low_findprog %s: decoding dumped\n", fname); + INC_RESOLV_MSG_DEPTH(); ret = decode_value(master_read_file(oname), (handler && handler->get_codec || get_codec)(fname, mkobj)); -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s returning decoded dump\n", fname); -#endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("low_findprog %s: dump decode ok\n", fname); return programs[fname] = ret; }; + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("low_findprog %s: dump decode failed\n", fname); m_delete(programs, fname); if (handler && handler->compile_warning) { handler->compile_warning(oname, 0, @@ -608,9 +637,8 @@ static program low_findprog(string pname, } } -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s compiling, mkobj:%O\n", fname, mkobj); -#endif + resolv_debug ("low_findprog %s: compiling, mkobj: %O\n", fname, mkobj); + INC_RESOLV_MSG_DEPTH(); programs[fname]=ret=__empty_program(0, fname); if ( mixed e=catch { ret=compile_file(fname, @@ -619,10 +647,14 @@ static program low_findprog(string pname, mkobj? (objects[ret]=__null_program()) : 0); } ) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("low_findprog %s: compilation failed\n", fname); m_delete(objects, ret); ret=programs[fname]=0; // Negative cache. throw(e); } + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("low_findprog %s: compilation ok\n", fname); break; #if constant(load_module) case ".so": @@ -632,9 +664,7 @@ static program low_findprog(string pname, } ret=load_module(fakeroot(fname)); -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s loaded binary\n", fname); -#endif + resolv_debug ("low_findprog %s: loaded binary\n", fname); #endif /* load_module */ } @@ -642,9 +672,7 @@ static program low_findprog(string pname, return programs[fname]=ret; } -#ifdef RESOLV_DEBUG - werror ("low_findprog: %s file not found\n", fname); -#endif + resolv_debug ("low_findprog %s: file not found\n", fname); return 0; } @@ -751,7 +779,12 @@ program cast_to_program(string pname, string current_file, object|void handler) { - return low_cast_to_program(pname, current_file, handler); + resolv_debug ("cast_to_program(%O, %O)\n", pname, current_file); + INC_RESOLV_MSG_DEPTH(); + program ret = low_cast_to_program(pname, current_file, handler); + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("cast_to_program(%O, %O) => %O\n", pname, current_file, ret); + return ret; } @@ -877,7 +910,12 @@ void create() //! is called from the compiler. program handle_inherit(string pname, string current_file, object|void handler) { - return cast_to_program(pname, current_file, handler); + resolv_debug ("handle_inherit(%O, %O)\n", pname, current_file); + INC_RESOLV_MSG_DEPTH(); + program ret = low_cast_to_program(pname, current_file, handler); + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("handle_inherit(%O, %O) => %O\n", pname, current_file, ret); + return ret; } mapping (program:object) objects=([object_program(this_object()):this_object()]); @@ -900,7 +938,11 @@ object low_cast_to_object(string oname, string current_file, //! may also receive more arguments in the future. object cast_to_object(string oname, string current_file) { + resolv_debug ("cast_to_object(%O, %O)\n", oname, current_file); + INC_RESOLV_MSG_DEPTH(); object o = low_cast_to_object(oname, current_file); + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("cast_to_object(%O, %O) => %O\n", oname, current_file, o); if (objectp (o)) return o; error("Cast '"+oname+"' to object failed"+ ((current_file && current_file!="-")?sprintf(" for '%s'",current_file):"")+".\n"); @@ -920,9 +962,7 @@ class dirnode void create(string d, object|void h) { -#ifdef MODULE_TRACE - werror("%*ndirnode(%O,%O);\n",sizeof(backtrace())-1,d,h); -#endif + resolv_debug ("dirnode(%O,%O) created\n",d,h); dirname=d; handler=h; fc[dirname]=this_object(); @@ -942,10 +982,8 @@ class dirnode { int `!() { -#ifdef MODULE_TRACE - werror("%*ndirnode(%O)->module_checker()->`!()\n", - sizeof(backtrace()),dirname); -#endif + resolv_debug ("dirnode(%O)->module_checker()->`!()\n",dirname); + INC_RESOLV_MSG_DEPTH(); if (catch { if(module=findmodule(dirname+"/module", handler)) { @@ -959,6 +997,10 @@ class dirnode cache=([]); _cache_full=0; } + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->module_checker()->`!() => %s\n", + dirname, !module ? "doesn't exist" : "exists"); + return !module; }) { // findmodule() failed. This can occur due to circularities // between encode_value()'ed programs. @@ -966,19 +1008,18 @@ class dirnode // "Cannot call functions in unfinished objects." // Pretend not to exist for now... + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->module_checker()->`!() => failure, doesn't exist\n", + dirname); return 1; } - - return !module; } mixed `[](string index) { -#ifdef MODULE_TRACE - werror("%*ndirnode(%O)->module_checker()[%O]\n", - sizeof(backtrace()),dirname,index); -#endif - if(module) return module[index]; + resolv_debug ("dirnode(%O)->module_checker()[%O] => %O\n", + dirname, index, module && module[index]); + return module && module[index]; } array(string) _indices() { if(module) return indices(module); } array _values() { if(module) return values(module); } @@ -986,24 +1027,18 @@ class dirnode static mixed ind(string index) { -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) ind[%O] -> ???\n", - sizeof(backtrace()),dirname,index); -#endif - if(module) + resolv_debug ("dirnode(%O)->ind(%O)\n", dirname, index); + INC_RESOLV_MSG_DEPTH(); + + if(module) { -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) module[%O] -> ???\n", - sizeof(backtrace()),dirname,index); -#endif mixed o; // _describe(module); if(!zero_type(o=module[index])) { -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) module[%O] -> %O\n", - sizeof(backtrace()),dirname,index, o); -#endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->ind(%O) => found %O\n", + dirname, index, o); return o; } } @@ -1017,36 +1052,32 @@ class dirnode ret=1; break; } - if(!ret) + if(!ret) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->ind(%O) => no file match\n", dirname, index); return UNDEFINED; + } - index = dirname+"/"+index; -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) findmodule(%O)\n", - sizeof(backtrace()), dirname, index); -#endif + string fullname = dirname+"/"+index; object o; - if(objectp(o=findmodule(index, handler))) + if(objectp(o=findmodule(fullname, handler))) { if(mixed tmp=o->_module_value) o=tmp; -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) findmodule(%O) ==> %O\n", - sizeof(backtrace()), dirname, index, o); -#endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->ind(%O) => found submodule %O\n", + dirname, index, o); return o; } - if (program p=cast_to_program( index, 0, handler )) + if (program p=cast_to_program( fullname, 0, handler )) { -#ifdef MODULE_TRACE - werror("%*nDirnode(%O) cast_to_program(%O) ==> %O\n", - sizeof(backtrace()), dirname, index, p); -#endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->ind(%O) => found subprogram %O\n", + dirname, index, p); return p; } -#ifdef MODULE_TRACE - werror("%*nDirnode(%O)->`[](%O) FAILED\n", - sizeof(backtrace()), dirname, index); -#endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("dirnode(%O)->ind(%O) => not found\n", + dirname, index); return UNDEFINED; } @@ -1060,7 +1091,7 @@ class dirnode if(!zero_type(ret=cache[index])) { #ifdef MODULE_TRACE - werror("%*nDirnode(%O) cache[%O] -> %O%s\n", + werror("%*nDirnode(%O) cache[%O] => %O%s\n", sizeof(backtrace()),dirname,index, ret, (ret != ZERO_TYPE)?"":" (zero_type)"); #endif @@ -1090,11 +1121,11 @@ class dirnode static int(0..1) _cache_full; void fill_cache() { -#ifdef RESOLV_DEBUG +#if 0 werror(describe_backtrace(({ sprintf("Filling cache in dirnode %O\n", dirname), backtrace() }))); -#endif /* RESOLV_DEBUG */ +#endif if (_cache_full) { return; } @@ -1173,10 +1204,14 @@ class joinnode void create(array(object|mapping) _joined_modules) { joined_modules = _joined_modules; + resolv_debug ("joinnode(%O) created\n", joined_modules); } static mixed ind(string index) { + resolv_debug ("joinnode(%O)->ind(%O)\n", joined_modules, index); + INC_RESOLV_MSG_DEPTH(); + array(mixed) res = ({}); foreach(joined_modules, object|mapping o) { @@ -1189,6 +1224,9 @@ class joinnode // Only join directorynodes (or joinnodes). res += ({ ret }); } else if ( !zero_type(ret) ) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("joinnode(%O)->ind(%O) => found %O\n", + joined_modules, index, ret); return (ret); } else { // Ignore @@ -1196,10 +1234,23 @@ class joinnode } } } - if (sizeof(res) > 1) - return joinnode(res); - else if (sizeof(res)) + + if (sizeof(res) > 1) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("joinnode(%O)->ind(%O) => new joinnode\n", + joined_modules, index); + return joinnode(res); + } + + else if (sizeof(res)) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("joinnode(%O)->ind(%O) => found %O\n", + joined_modules, index, res[0]); return res[0]; + } + + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("joinnode(%O)->ind(%O) => not found\n", joined_modules, index); return UNDEFINED; } @@ -1228,10 +1279,10 @@ class joinnode static int _cache_full; void fill_cache() { -#ifdef RESOLV_DEBUG +#if 0 werror(describe_backtrace(({ "Filling cache in joinnode\n", backtrace() }))); -#endif /* RESOLV_DEBUG */ +#endif if (_cache_full) { return; } @@ -1280,31 +1331,44 @@ mapping(string:mixed) fc=([]); object findmodule(string fullname, object|void handler) { object o; -#ifdef MODULE_TRACE - werror("%*nfindmodule(%O)\n",sizeof(backtrace()),fullname); -#endif + resolv_debug ("findmodule(%O)\n", fullname); if(!zero_type(o=fc[fullname])) { -// werror("fc[%O] -> %O\n",fullname, o); - if (objectp(o)) return o; - if (o == 0) return UNDEFINED; - return o; + if (objectp(o) || o != 0) { + resolv_debug ("findmodule(%O) => found %O (cached)\n", fullname, o); + return o; + } + resolv_debug ("findmodule(%O) => not found (cached)\n", fullname); + return UNDEFINED; } if(Stat stat=master_file_stat(fakeroot(fullname+".pmod"))) { - if(stat[1]==-2) + if(stat[1]==-2) { + resolv_debug ("findmodule(%O) => new dirnode\n", fullname); return dirnode(fullname+".pmod", handler); + } } - if(objectp (o = low_cast_to_object(fullname+".pmod", "/.", handler))) + INC_RESOLV_MSG_DEPTH(); + + if(objectp (o = low_cast_to_object(fullname+".pmod", "/.", handler))) { + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("findmodule(%O) => got object %O\n", fullname, o); return fc[fullname]=o; + } #if constant(load_module) - if(master_file_stat(fakeroot(fullname+".so"))) - return fc[fullname] = low_cast_to_object(fullname, "/.", handler); + if(master_file_stat(fakeroot(fullname+".so"))) { + o = fc[fullname] = low_cast_to_object(fullname, "/.", handler); + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("findmodule(%O) => got .so object %O\n", fullname, o); + return o; + } #endif + DEC_RESOLV_MSG_DEPTH(); + resolv_debug ("findmodule(%O) => not found\n", fullname); return fc[fullname] = 0; } @@ -1320,14 +1384,17 @@ mixed handle_import(string what, string|void current_file, object|void handler) } else { path = combine_path_with_cwd(what); } -#ifdef MODULE_TRACE - werror("%*nhandle_import(%O, %O, %O)\n", - sizeof(backtrace()), what, current_file, handler); -#endif /* MODULE_TRACE */ if (handler) { + resolv_debug ("handle_import(%O, %O, %O) => new dirnode with handler\n", + what, current_file, handler); return dirnode(path, handler); } - if(fc[path]) return fc[path]; + if(fc[path]) { + resolv_debug ("handle_import(%O, %O) => found %O (cached)\n", + what, current_file, fc[path]); + return fc[path]; + } + resolv_debug ("handle_import(%O, %O) => new dirnode\n", what, current_file); return dirnode(path); } @@ -1530,15 +1597,13 @@ class CompatResolver mixed resolv(string identifier, string|void current_file, object|void current_handler) { -#ifdef RESOLV_DEBUG - werror("Resolv(%O, %O)\n",identifier, current_file); -#endif /* RESOLV_DEBUG */ + resolv_debug("resolv(%O, %O)\n",identifier, current_file); + INC_RESOLV_MSG_DEPTH(); // FIXME: Support having the cache in the handler? if( no_resolv[ identifier ] ) { -#ifdef RESOLV_DEBUG - werror("Resolv(%O, %O) => excluded\n",identifier, current_file); -#endif /* RESOLV_DEBUG */ + DEC_RESOLV_MSG_DEPTH(); + resolv_debug("resolv(%O, %O) => excluded\n",identifier, current_file); return UNDEFINED; } @@ -1552,12 +1617,12 @@ class CompatResolver string id=identifier+":"+(current_file ? dirname(current_file) : "-"); if( zero_type (ret = resolv_cache[id]) != 1 ) { -// werror("Resolv cached(%O) => %O (%d)\n",id,resolv_cache[id],zero_type(resolv_cache[id])); #ifdef RESOLV_DEBUG + DEC_RESOLV_MSG_DEPTH(); if (ret == ZERO_TYPE) - werror("Resolv(%O, %O) => not found (cached)\n",identifier, current_file); + resolv_debug("resolv(%O, %O) => not found (cached)\n",identifier, current_file); else - werror("Resolv(%O, %O) => found %O (cached)\n",identifier, current_file, ret); + resolv_debug("resolv(%O, %O) => found %O (cached)\n",identifier, current_file, ret); #endif /* RESOLV_DEBUG */ return ret == ZERO_TYPE ? UNDEFINED : ret; } @@ -1569,11 +1634,12 @@ class CompatResolver ret=ret[index]; } resolv_cache[id] = zero_type (ret) ? ZERO_TYPE : ret; + DEC_RESOLV_MSG_DEPTH(); #ifdef RESOLV_DEBUG if (zero_type (ret)) - werror("Resolv(%O, %O) => not found\n",identifier, current_file); + resolv_debug("resolv(%O, %O) => not found\n",identifier, current_file); else - werror("Resolv(%O, %O) => found %O\n",identifier, current_file, ret); + resolv_debug("resolv(%O, %O) => found %O\n",identifier, current_file, ret); #endif /* RESOLV_DEBUG */ return ret; }