a2faf61999-12-01Martin Stjernholm /* -*- Pike -*- *
a20af62000-09-26Fredrik Hübinette (Hubbe)  * $Id: master.pike.in,v 1.132 2000/09/26 18:58:56 hubbe Exp $
ce8aee1998-04-21Per Hedbor  *
ca2b071998-03-28Henrik Grubbström (Grubba)  * Master-file for Pike. * * Based on master.pike 1.67. */
c896b41998-04-29Henrik Grubbström (Grubba) // Some configurable parameters useful for debugging
a20af62000-09-26Fredrik Hübinette (Hubbe) #pike __VERSION__
bec57d1999-09-06Fredrik Hübinette (Hubbe) #define PIKE_AUTORELOAD
c896b41998-04-29Henrik Grubbström (Grubba) // Used by describe_backtrace() et al. #if !defined(BT_MAX_STRING_LEN) || (BT_MAX_STRING_LEN <= 0) #undef BT_MAX_STRING_LEN
a858201999-10-15Fredrik Hübinette (Hubbe) #define BT_MAX_STRING_LEN 200
c896b41998-04-29Henrik Grubbström (Grubba) #endif /* !defined(BT_MAX_STRING_LEN) || (BT_MAX_STRING_LEN <= 0) */
d4fd0a1999-12-06Henrik Grubbström (Grubba) constant bt_max_string_len = BT_MAX_STRING_LEN;
e115cb1999-12-09Henrik Grubbström (Grubba) // Enables the out of date warning in low_find_prog(). #ifndef OUT_OF_DATE_WARNING #define OUT_OF_DATE_WARNING 1 #endif /* OUT_OF_DATE_WARNING */ constant out_of_date_warning = OUT_OF_DATE_WARNING;
df2c632000-08-02Henrik Grubbström (Grubba) #ifndef PIKE_WARNINGS #define PIKE_WARNINGS 0 #endif /* PIKE_WARNINGS */
c896b41998-04-29Henrik Grubbström (Grubba) /* * Functions begin here. */
26f3da2000-07-11Fredrik Hübinette (Hubbe) #ifdef PIKE_FAKEROOT object o; string fakeroot(string s) { string tmp1=combine_path_with_cwd(s); #ifdef PIKE_FAKEROOT_OMIT foreach(PIKE_FAKEROOT_OMIT/":", string x) if(glob(x,tmp1)) return s; #endif return PIKE_FAKEROOT+tmp1; } #else #define fakeroot(X) X #endif
ca2b071998-03-28Henrik Grubbström (Grubba) int is_absolute_path(string p) { #ifdef __NT__ p=replace(p,"\\","/"); if(sscanf(p,"%[a-zA-Z]:",string s) && sizeof(s)==1) return 1;
471ed91998-04-24Fredrik Hübinette (Hubbe) #define IS_ABSOLUTE_PATH is_absolute_path #else #define IS_ABSOLUTE_PATH(X) ((X)[0]=='/')
ca2b071998-03-28Henrik Grubbström (Grubba) #endif return p[0]=='/'; }
bbf4702000-04-10Henrik Grubbström (Grubba) array(string) explode_path(string p)
ca2b071998-03-28Henrik Grubbström (Grubba) { #ifdef __NT__ p=replace(p,"\\","/");
471ed91998-04-24Fredrik Hübinette (Hubbe) #define EXPLODE_PATH(X) (replace((X),"\\","/")/"/") #else #define EXPLODE_PATH(X) ((X)/"/")
ca2b071998-03-28Henrik Grubbström (Grubba) #endif return p/"/"; } string dirname(string x) {
afa1292000-02-19Martin Nilsson  array(string) tmp=EXPLODE_PATH(x);
ca2b071998-03-28Henrik Grubbström (Grubba)  return tmp[..sizeof(tmp)-2]*"/"; } string basename(string x) {
afa1292000-02-19Martin Nilsson  array(string) tmp=EXPLODE_PATH(x);
ca2b071998-03-28Henrik Grubbström (Grubba)  return tmp[-1]; }
471ed91998-04-24Fredrik Hübinette (Hubbe) #define DIRNAME dirname #define BASENAME(X) (EXPLODE_PATH(X)[-1])
ca2b071998-03-28Henrik Grubbström (Grubba)  #define GETCWD_CACHE #define FILE_STAT_CACHE #define UNDEFINED (([])[0])
dbe79a1999-12-07Henrik Grubbström (Grubba) #define error(X) throw( ({ (X), backtrace()/*[0..sizeof(backtrace())-2]*/ }) )
ca2b071998-03-28Henrik Grubbström (Grubba) 
df2c632000-08-02Henrik Grubbström (Grubba) int want_warnings = PIKE_WARNINGS;
ca2b071998-03-28Henrik Grubbström (Grubba) 
bec57d1999-09-06Fredrik Hübinette (Hubbe) #ifdef PIKE_AUTORELOAD int autoreload_on; int newest; #define AUTORELOAD_CHECK_FILE(X) \ if(autoreload_on) if(mixed fnord=master_file_stat(X)) if(fnord[3]>newest) newest=fnord[3]; #define AUTORELOAD_BEGIN() \ int ___newest=newest; \ newest=0 #define AUTORELOAD_FINISH(VAR, CACHE, FILE) \ if(autoreload_on) { \ if(CACHE [ FILE ] && newest <= load_time[FILE]) { \ VAR = CACHE [ FILE ]; \ } \ } \ load_time[FILE]=time(); \ if(___newest > newest) newest=___newest; mapping(string:int) load_time=([]); #else #define AUTORELOAD_CHECK_FILE(X) #define AUTORELOAD_BEGIN() #define AUTORELOAD_FINISH(VAR,CACHE,FILE) #endif
a20af62000-09-26Fredrik Hübinette (Hubbe) int compat_major=-1; int compat_minor=-1;
01d3c91999-11-04Henrik Grubbström (Grubba) program compile_string(string data, void|string name, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) {
a20af62000-09-26Fredrik Hübinette (Hubbe)  return compile(cpp(data,name||"-", 0, handler, compat_major, compat_minor), handler, compat_major, compat_minor);
ca2b071998-03-28Henrik Grubbström (Grubba) }
26f3da2000-07-11Fredrik Hübinette (Hubbe) 
d8a6fc2000-03-25Fredrik Hübinette (Hubbe) string master_read_file(string file) { object o=_static_modules.files()->Fd();
26f3da2000-07-11Fredrik Hübinette (Hubbe)  if(o->open(fakeroot(file),"r"))
d8a6fc2000-03-25Fredrik Hübinette (Hubbe)  return o->read(); return 0; }
01d3c91999-11-04Henrik Grubbström (Grubba) program compile_file(string file, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) {
bec57d1999-09-06Fredrik Hübinette (Hubbe)  AUTORELOAD_CHECK_FILE(file);
d8a6fc2000-03-25Fredrik Hübinette (Hubbe)  return compile(cpp(master_read_file(file),
a20af62000-09-26Fredrik Hübinette (Hubbe)  file, 1, handler, compat_major, compat_minor), handler, compat_major, compat_minor );
ca2b071998-03-28Henrik Grubbström (Grubba) } #ifdef GETCWD_CACHE string current_path; int cd(string s) { current_path=0; return predef::cd(s); } string getcwd() { return current_path || (current_path=predef::getcwd()); } #endif string combine_path_with_cwd(string path) {
471ed91998-04-24Fredrik Hübinette (Hubbe)  return combine_path(IS_ABSOLUTE_PATH(path)?"/":getcwd(),path);
ca2b071998-03-28Henrik Grubbström (Grubba) } #ifdef FILE_STAT_CACHE #define FILE_STAT_CACHE_TIME 20 int invalidate_time; mapping(string:multiset(string)) dir_cache = ([]);
61a4242000-08-27Mirar (Pontus Hagland) #define Stat _static_modules.files.Stat Stat master_file_stat(string x)
ca2b071998-03-28Henrik Grubbström (Grubba) { string file, dir=combine_path_with_cwd(x);
471ed91998-04-24Fredrik Hübinette (Hubbe)  file=BASENAME(dir); dir=DIRNAME(dir);
ca2b071998-03-28Henrik Grubbström (Grubba)  multiset(string) d; if(time() > invalidate_time) { dir_cache=([]); invalidate_time=time()+FILE_STAT_CACHE_TIME; } if(zero_type(d=dir_cache[dir])) {
afa1292000-02-19Martin Nilsson  if(array(string) tmp=get_dir(dir))
ca2b071998-03-28Henrik Grubbström (Grubba)  { d=dir_cache[dir]=aggregate_multiset(@tmp); }else{ dir_cache[dir]=0; } } if(d && !d[file]) return 0; return predef::file_stat(x); } #else #define master_file_stat file_stat #endif mapping (string:string) environment=([]);
944d5b1999-12-05Henrik Grubbström (Grubba) string|mapping(string:string) getenv(string|void s)
ca2b071998-03-28Henrik Grubbström (Grubba) {
df2c632000-08-02Henrik Grubbström (Grubba)  if(!s) return environment + ([]); return environment[s]; } #if 0 variant mapping(string:string) getenv() { return environment + ([]); } variant string getenv(string s) { return environment[s]; } function(:mapping(string:string))|function(string:string) getenv(s) { if(!s) return environment + ([]); return environment[s]; } mapping(string:string) getenv() | string getenv(string s) { if(!s) return environment + ([]);
ca2b071998-03-28Henrik Grubbström (Grubba)  return environment[s]; }
df2c632000-08-02Henrik Grubbström (Grubba) #endif /* 0 */
ca2b071998-03-28Henrik Grubbström (Grubba)  void putenv(string var, string val) { environment[var]=val; }
4c3f7d2000-04-13Per Hedbor string normalize_path( string X ) { #ifndef __NT__ return X; #else return replace(X,"\\","/"); #endif }
ca2b071998-03-28Henrik Grubbström (Grubba)  mapping (string:program) programs=(["/master":object_program(this_object())]); #define capitalize(X) (upper_case((X)[..0])+(X)[1..])
6d926c1999-11-26Henrik Grubbström (Grubba) array(string) query_precompiled_names(string fname) { // Filenames of potential precompiled files in priority order. return ({ fname + ".o" }); }
6330192000-02-10Fredrik Hübinette (Hubbe) #if constant(_static_modules.Builtin.mutex) #define THREADED object compilation_mutex = _static_modules.Builtin()->mutex(); #endif
10e16f1999-11-04Henrik Grubbström (Grubba) static program low_findprog(string pname, string ext, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) { program ret;
61a4242000-08-27Mirar (Pontus Hagland)  Stat s;
ca2b071998-03-28Henrik Grubbström (Grubba)  string fname=pname+ext;
bec57d1999-09-06Fredrik Hübinette (Hubbe) 
6330192000-02-10Fredrik Hübinette (Hubbe) #ifdef THREADED
3b11422000-02-13Henrik Grubbström (Grubba)  object key; // FIXME: The catch is needed, since we might be called in // a context when threads are disabled. // (compile() disables threads).
098c8a2000-03-30Henrik Grubbström (Grubba)  mixed err = catch {
3b11422000-02-13Henrik Grubbström (Grubba)  key=compilation_mutex->lock(2); };
098c8a2000-03-30Henrik Grubbström (Grubba)  if (err) { werror(sprintf("low_findprog: Caught spurious error:\n" "%s\n", describe_backtrace(err))); }
6330192000-02-10Fredrik Hübinette (Hubbe) #endif
bec57d1999-09-06Fredrik Hübinette (Hubbe) #ifdef PIKE_AUTORELOAD if(!autoreload_on || load_time[fname]>=time()) #endif {
6e2ebb1999-12-28Martin Stjernholm  if(!zero_type (ret=programs[fname])) return ret;
bec57d1999-09-06Fredrik Hübinette (Hubbe)  }
41ee482000-02-28Fredrik Hübinette (Hubbe) #ifdef __NT__ // Ugly kluge to work better with cygwin32 if(getenv("OSTYPE")=="cygwin32") { string tmp=fname[..1]; if((tmp=="//" || tmp=="\\\\") && (fname[3]=='/' || fname[3]=='\\')) { if(!master_file_stat(fname)) { fname=fname[2..2]+":"+fname[3..]; } } } #endif
26f3da2000-07-11Fredrik Hübinette (Hubbe)  if( (s=master_file_stat(fakeroot(fname))) && s[1]>=0 )
ca2b071998-03-28Henrik Grubbström (Grubba)  {
bec57d1999-09-06Fredrik Hübinette (Hubbe)  AUTORELOAD_BEGIN();
14fc641999-11-26Henrik Grubbström (Grubba) 
6e2ebb1999-12-28Martin Stjernholm #ifdef PIKE_AUTORELOAD
14fc641999-11-26Henrik Grubbström (Grubba)  if (load_time[fname] > s[3])
6e2ebb1999-12-28Martin Stjernholm  if (!zero_type (ret=programs[fname])) return ret; #endif
14fc641999-11-26Henrik Grubbström (Grubba) 
ca2b071998-03-28Henrik Grubbström (Grubba)  switch(ext) { case "": case ".pike":
6d926c1999-11-26Henrik Grubbström (Grubba)  foreach(query_precompiled_names(fname), string oname) {
61a4242000-08-27Mirar (Pontus Hagland)  if(Stat s2=master_file_stat(fakeroot(oname)))
6d926c1999-11-26Henrik Grubbström (Grubba)  { if(s2[1]>=0 && s2[3]>=s[3]) { mixed err=catch { AUTORELOAD_CHECK_FILE(oname); return programs[fname] =
d8a6fc2000-03-25Fredrik Hübinette (Hubbe)  decode_value(master_read_file(oname),
6d926c1999-11-26Henrik Grubbström (Grubba)  Codec()); }; if (handler) { handler->compile_warning(oname, 0, sprintf("Decode failed:\n" "\t%s", err[0])); } else { compile_warning(oname, 0, sprintf("Decode failed:\n" "\t%s", err[0])); }
e115cb1999-12-09Henrik Grubbström (Grubba)  } else if (out_of_date_warning) {
6d926c1999-11-26Henrik Grubbström (Grubba)  if (handler) { handler->compile_warning(oname, 0, "Compiled file is out of date\n"); } else { compile_warning(oname, 0, "Compiled file is out of date\n"); }
10e16f1999-11-04Henrik Grubbström (Grubba)  }
b085961998-05-19Fredrik Hübinette (Hubbe)  }
471ed91998-04-24Fredrik Hübinette (Hubbe)  }
bec57d1999-09-06Fredrik Hübinette (Hubbe) 
6330192000-02-10Fredrik Hübinette (Hubbe) // werror("2.5: %O\n",fname);
bec57d1999-09-06Fredrik Hübinette (Hubbe) 
ca2b071998-03-28Henrik Grubbström (Grubba)  if ( mixed e=catch { ret=compile_file(fname); } ) {
6330192000-02-10Fredrik Hübinette (Hubbe) // werror("-3: %O\n",fname);
c46d682000-01-05Martin Stjernholm  programs[fname]=0;
bf38862000-01-05Martin Stjernholm  if(arrayp(e) && sizeof(e) && e[0] == "Compilation failed.\n")
c46d682000-01-05Martin Stjernholm  e[1]=({}); throw(e);
ca2b071998-03-28Henrik Grubbström (Grubba)  } break; #if constant(load_module) case ".so":
caa3221998-04-15Henrik Grubbström (Grubba)  if (fname == "") { werror(sprintf("low_find_prog(\"%s\", \"%s\") => load_module(\"\")\n" "%s\n", pname, ext, describe_backtrace(backtrace()))); }
26f3da2000-07-11Fredrik Hübinette (Hubbe)  ret=load_module(fakeroot(fname));
ca2b071998-03-28Henrik Grubbström (Grubba) #endif /* load_module */ }
bec57d1999-09-06Fredrik Hübinette (Hubbe)  AUTORELOAD_FINISH(ret,programs,fname);
6e2ebb1999-12-28Martin Stjernholm 
6330192000-02-10Fredrik Hübinette (Hubbe) // werror("3: %O\n",fname);
ca2b071998-03-28Henrik Grubbström (Grubba)  return programs[fname]=ret; }
6e2ebb1999-12-28Martin Stjernholm  return 0;
ca2b071998-03-28Henrik Grubbström (Grubba) }
10e16f1999-11-04Henrik Grubbström (Grubba) static program findprog(string pname, string ext, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) { switch(ext) { case ".pike": case ".so":
10e16f1999-11-04Henrik Grubbström (Grubba)  return low_findprog(pname,ext,handler);
ca2b071998-03-28Henrik Grubbström (Grubba)  default: pname+=ext; return
10e16f1999-11-04Henrik Grubbström (Grubba)  low_findprog(pname,"", handler) || low_findprog(pname,".pike", handler) || low_findprog(pname,".so", handler);
ca2b071998-03-28Henrik Grubbström (Grubba)  } } /* This function is called when the driver wants to cast a string * to a program, this might be because of an explicit cast, an inherit * or a implict cast. In the future it might receive more arguments, * to aid the master finding the right program. */
10e16f1999-11-04Henrik Grubbström (Grubba) program cast_to_program(string pname, string current_file, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) { string ext; string nname;
471ed91998-04-24Fredrik Hübinette (Hubbe)  array(string) tmp=EXPLODE_PATH(pname);
ca2b071998-03-28Henrik Grubbström (Grubba)  if(sscanf(reverse(tmp[-1]),"%s.%s",ext, nname)) { ext="."+reverse(ext); tmp[-1]=reverse(nname); pname=tmp*"/"; }else{ ext=""; }
471ed91998-04-24Fredrik Hübinette (Hubbe)  if(IS_ABSOLUTE_PATH(pname))
ca2b071998-03-28Henrik Grubbström (Grubba)  { pname=combine_path("/",pname);
10e16f1999-11-04Henrik Grubbström (Grubba)  return findprog(pname,ext,handler);
ca2b071998-03-28Henrik Grubbström (Grubba)  }else{ string cwd; if(current_file) {
471ed91998-04-24Fredrik Hübinette (Hubbe)  cwd=DIRNAME(current_file);
ca2b071998-03-28Henrik Grubbström (Grubba)  }else{ cwd=getcwd(); }
10e16f1999-11-04Henrik Grubbström (Grubba)  if(program ret=findprog(combine_path(cwd,pname),ext,handler))
ca2b071998-03-28Henrik Grubbström (Grubba)  return ret; foreach(pike_program_path, string path)
10e16f1999-11-04Henrik Grubbström (Grubba)  if(program ret=findprog(combine_path(path,pname),ext,handler))
ca2b071998-03-28Henrik Grubbström (Grubba)  return ret; return 0; } } /* This function is called when an error occurs that is not caught * with catch(). It's argument consists of: * ({ error_string, backtrace }) where backtrace is the output from the * backtrace() efun. */
06d6d31999-12-13Henrik Grubbström (Grubba) void handle_error(array(mixed)|object trace)
ca2b071998-03-28Henrik Grubbström (Grubba) { predef::trace(0);
62e87b1998-04-14Fredrik Hübinette (Hubbe)  if(mixed x=catch { werror(describe_backtrace(trace)); }) { werror("Error in handle_error in master object:\n");
aa73fc1999-10-21Fredrik Hübinette (Hubbe)  if(catch { werror("%O\nOriginal error:\n%O\n",x,trace); }) { werror("sprintf() failed to write error.\n"); }
62e87b1998-04-14Fredrik Hübinette (Hubbe)  }
ca2b071998-03-28Henrik Grubbström (Grubba) } object new(mixed prog, mixed ... args) { if(stringp(prog))
67276c1999-04-08Fredrik Hübinette (Hubbe)  { if(program p=cast_to_program(prog,backtrace()[-2][0])) return p(@args); else error(sprintf("new: failed to find program %s.\n",prog)); }
ca2b071998-03-28Henrik Grubbström (Grubba)  return prog(@args); }
c5cc2d1998-04-29Henrik Grubbström (Grubba) function clone = new; /* This array contains the names of the functions * that a replacing master-object may want to override. */ constant master_efuns = ({ "basename", "dirname", "is_absolute_path", "explode_path", "compile_string", "compile_file", "add_include_path", "remove_include_path", "add_module_path", "remove_module_path", "add_program_path", "remove_program_path", "describe_backtrace",
a66ff22000-01-11Martin Stjernholm  "describe_error",
c5cc2d1998-04-29Henrik Grubbström (Grubba)  "new", "clone",
4c3f7d2000-04-13Per Hedbor  "normalize_path",
c5cc2d1998-04-29Henrik Grubbström (Grubba)  "getenv", "putenv", #ifdef GETCWD_CACHE "cd", "getcwd", #endif });
ca2b071998-03-28Henrik Grubbström (Grubba) /* Note that create is called before add_precompiled_program */ void create() {
c5cc2d1998-04-29Henrik Grubbström (Grubba)  object o = this_object();
ca2b071998-03-28Henrik Grubbström (Grubba) 
c5cc2d1998-04-29Henrik Grubbström (Grubba)  foreach(master_efuns, string e) { if (o[e]) { add_constant(e, o[e]); } else { throw(({ sprintf("Function %O is missing from master.pike.\n", e), backtrace() })); } } add_constant("strlen", sizeof); add_constant("UNDEFINED", UNDEFINED); add_constant("write", _static_modules.files()->_stdout->write);
ca2b071998-03-28Henrik Grubbström (Grubba) 
e37a3e1999-10-09Fredrik Hübinette (Hubbe) #if "¤share_prefix¤"[0]!='¤' // add path for architecture-dependant files add_include_path("¤share_prefix¤/include"); add_module_path("¤share_prefix¤/modules"); #endif #if "¤lib_prefix¤"[0]!='¤' // add path for architecture-dependant files add_include_path("¤lib_prefix¤/include"); add_module_path("¤lib_prefix¤/modules"); #endif
ca2b071998-03-28Henrik Grubbström (Grubba) } /* * This function is called whenever a inherit is called for. * It is supposed to return the program to inherit. * The first argument is the argument given to inherit, and the second * is the file name of the program currently compiling. Note that the * file name can be changed with #line, or set by compile_string, so * it can not be 100% trusted to be a filename. * previous_object(), can be virtually anything in this function, as it * is called from the compiler. */
10e16f1999-11-04Henrik Grubbström (Grubba) program handle_inherit(string pname, string current_file, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) {
10e16f1999-11-04Henrik Grubbström (Grubba)  return cast_to_program(pname, current_file, handler);
ca2b071998-03-28Henrik Grubbström (Grubba) } mapping (program:object) objects=([object_program(this_object()):this_object()]); object low_cast_to_object(string oname, string current_file) { program p; object o; p=cast_to_program(oname, current_file); if(!p) return 0; if(!(o=objects[p])) o=objects[p]=p(); return o; } /* This function is called when the drivers wants to cast a string * to an object because of an implict or explicit cast. This function * may also receive more arguments in the future. */ object cast_to_object(string oname, string current_file) { if(object o=low_cast_to_object(oname, current_file)) return o;
ac0fed2000-03-25Fredrik Hübinette (Hubbe)  error("Cast '"+oname+"' to object failed"+
b1693a2000-04-07Fredrik Hübinette (Hubbe)  ((current_file && current_file!="-")?sprintf(" for '%s'",current_file):"")+".\n");
ac0fed2000-03-25Fredrik Hübinette (Hubbe)  return 0;
ca2b071998-03-28Henrik Grubbström (Grubba) } class dirnode {
4817482000-05-11Martin Stjernholm  constant is_resolv_dirnode = 1;
ca2b071998-03-28Henrik Grubbström (Grubba)  string dirname;
14bb592000-05-06Fredrik Hübinette (Hubbe)  mixed module=module_checker();
098c8a2000-03-30Henrik Grubbström (Grubba)  mapping(string:mixed) cache=([]); array(string) files;
ca2b071998-03-28Henrik Grubbström (Grubba) 
cc2c071998-04-19Fredrik Hübinette (Hubbe)  void create(string name)
ca2b071998-03-28Henrik Grubbström (Grubba)  { dirname=name;
14bb592000-05-06Fredrik Hübinette (Hubbe)  }
ca2b071998-03-28Henrik Grubbström (Grubba) 
14bb592000-05-06Fredrik Hübinette (Hubbe)  class module_checker { int `!() { module=0; if(module=findmodule(dirname+"/module")) if(mixed tmp=module->_module_value) module=tmp; return !module; }
52c5792000-05-23Fredrik Hübinette (Hubbe)  mixed `[](string index) { if(module) return module[index]; } array(string) _indices() { if(module) return indices(module); } array _values() { if(module) return values(module); }
ca2b071998-03-28Henrik Grubbström (Grubba)  }
098c8a2000-03-30Henrik Grubbström (Grubba)  static mixed ind(string index)
ca2b071998-03-28Henrik Grubbström (Grubba)  {
e118831999-12-22Per Hedbor  if(module) {
a2faf61999-12-01Martin Stjernholm  object o; if(!zero_type(o=module[index])) return o; }
ca2b071998-03-28Henrik Grubbström (Grubba) 
e118831999-12-22Per Hedbor  if( !files )
26f3da2000-07-11Fredrik Hübinette (Hubbe)  files = get_dir(fakeroot(dirname));
e118831999-12-22Per Hedbor  int ret; foreach( files, string s ) { if( search(s, index)!=-1 || search(index,s)!=-1 ) { ret=1; break; } } if(!ret) return UNDEFINED;
ca2b071998-03-28Henrik Grubbström (Grubba)  index = dirname+"/"+index;
cc2c071998-04-19Fredrik Hübinette (Hubbe)  if(object o=findmodule(index))
ca2b071998-03-28Henrik Grubbström (Grubba)  { if(mixed tmp=o->_module_value) o=tmp; return o; }
73e9551999-12-28Martin Stjernholm  if (program p=cast_to_program( index, 0 )) return p; return UNDEFINED;
ca2b071998-03-28Henrik Grubbström (Grubba)  }
098c8a2000-03-30Henrik Grubbström (Grubba)  mixed `[](string index)
ca2b071998-03-28Henrik Grubbström (Grubba)  { mixed ret; if(!zero_type(ret=cache[index])) {
a2faf61999-12-01Martin Stjernholm  if(ret!=0) return ret;
ca2b071998-03-28Henrik Grubbström (Grubba)  return UNDEFINED; } return cache[index]=ind(index); }
3e4b811998-10-16Henrik Grubbström (Grubba) 
098c8a2000-03-30Henrik Grubbström (Grubba)  static int _cache_full;
3e4b811998-10-16Henrik Grubbström (Grubba)  void fill_cache() {
f4f08d1999-02-26Henrik Grubbström (Grubba) #ifdef RESOLV_DEBUG werror(describe_backtrace(({ sprintf("Filling cache in dirnode %O\n", dirname), backtrace() }))); #endif /* RESOLV_DEBUG */
3e4b811998-10-16Henrik Grubbström (Grubba)  if (_cache_full) { return; } if (module) { foreach(indices(module), string index) { cache[index] = module[index]; } }
e118831999-12-22Per Hedbor  if( !files )
26f3da2000-07-11Fredrik Hübinette (Hubbe)  files = get_dir(fakeroot(dirname));
e118831999-12-22Per Hedbor  foreach(files, string fname) {
0e68e62000-02-04Henrik Grubbström (Grubba)  mixed err = catch {
3e4b811998-10-16Henrik Grubbström (Grubba)  if (((< ".pike", ".pmod" >)[fname[sizeof(fname)-5..]]) && !zero_type(`[](fname[..sizeof(fname)-6]))) { continue;
0e68e62000-02-04Henrik Grubbström (Grubba)  } else if ((fname[sizeof(fname)-3..] == ".so") &&
3e4b811998-10-16Henrik Grubbström (Grubba)  !zero_type(`[](fname[..sizeof(fname)-4]))) { continue; } };
0e68e62000-02-04Henrik Grubbström (Grubba)  if (err) { compile_warning(dirname+"."+fname, 0, sprintf("Compilation failed:\n" "%s\n", describe_backtrace(err))); }
3e4b811998-10-16Henrik Grubbström (Grubba)  } _cache_full = 1; } array(string) _indices() {
098c8a2000-03-30Henrik Grubbström (Grubba)  // werror("indices(%O) called\n", dirname);
3e4b811998-10-16Henrik Grubbström (Grubba)  fill_cache();
a2faf61999-12-01Martin Stjernholm  return indices(filter(cache, lambda(mixed x){ return x!=0; }));
3e4b811998-10-16Henrik Grubbström (Grubba)  } array(mixed) _values() {
098c8a2000-03-30Henrik Grubbström (Grubba)  // werror("values(%O) called\n", dirname);
3e4b811998-10-16Henrik Grubbström (Grubba)  fill_cache();
b7e0891999-10-10Marcus Comstedt  return values(cache)-({0});
3e4b811998-10-16Henrik Grubbström (Grubba)  }
52c5792000-05-23Fredrik Hübinette (Hubbe)  string _sprintf(int as) { return sprintf("master()->dirnode(%O)",dirname); }
ca2b071998-03-28Henrik Grubbström (Grubba) };
6e2ebb1999-12-28Martin Stjernholm static class ZERO_TYPE {};
94257b1998-10-16Henrik Grubbström (Grubba) class joinnode {
4817482000-05-11Martin Stjernholm  constant is_resolv_joinnode = 1;
94257b1998-10-16Henrik Grubbström (Grubba)  array(object|mapping) joined_modules;
098c8a2000-03-30Henrik Grubbström (Grubba)  mapping(string:mixed) cache=([]);
94257b1998-10-16Henrik Grubbström (Grubba) 
52c5792000-05-23Fredrik Hübinette (Hubbe)  string _sprintf(int as) { return sprintf("master()->joinnode(%O)",joined_modules); }
94257b1998-10-16Henrik Grubbström (Grubba)  void create(array(object|mapping) _joined_modules) { joined_modules = _joined_modules; }
098c8a2000-03-30Henrik Grubbström (Grubba)  static mixed ind(string index)
94257b1998-10-16Henrik Grubbström (Grubba)  { array(mixed) res = ({});
ca051c1999-11-23Per Hedbor  foreach(joined_modules, object|mapping o) {
94257b1998-10-16Henrik Grubbström (Grubba)  mixed ret;
ca051c1999-11-23Per Hedbor  if (!zero_type(ret = o[index])) {
8b307e1998-10-17Henrik Grubbström (Grubba)  if (objectp(ret = o[index]) &&
3ad5d62000-05-13Martin Stjernholm  (ret->is_resolv_dirnode || ret->is_resolv_joinnode))
ca051c1999-11-23Per Hedbor  {
8b307e1998-10-17Henrik Grubbström (Grubba)  // Only join directorynodes (or joinnodes). res += ({ ret });
8cdeed2000-09-15Mirar (Pontus Hagland)  } else if ( !zero_type(ret) ) {
ca051c1999-11-23Per Hedbor  return (ret);
8b307e1998-10-17Henrik Grubbström (Grubba)  } else { // Ignore continue; }
94257b1998-10-16Henrik Grubbström (Grubba)  } }
ca051c1999-11-23Per Hedbor  if (sizeof(res) > 1) return joinnode(res); else if (sizeof(res))
94257b1998-10-16Henrik Grubbström (Grubba)  return res[0]; return UNDEFINED; }
098c8a2000-03-30Henrik Grubbström (Grubba)  mixed `[](string index)
94257b1998-10-16Henrik Grubbström (Grubba)  {
098c8a2000-03-30Henrik Grubbström (Grubba)  mixed ret;
94257b1998-10-16Henrik Grubbström (Grubba)  if (!zero_type(ret = cache[index])) { if (ret != ZERO_TYPE) { return ret; } return UNDEFINED; } ret = ind(index); if (zero_type(ret)) { cache[index] = ZERO_TYPE; } else { cache[index] = ret; } return ret; }
098c8a2000-03-30Henrik Grubbström (Grubba)  static int _cache_full;
3e4b811998-10-16Henrik Grubbström (Grubba)  void fill_cache() {
f4f08d1999-02-26Henrik Grubbström (Grubba) #ifdef RESOLV_DEBUG werror(describe_backtrace(({ "Filling cache in joinnode\n", backtrace() }))); #endif /* RESOLV_DEBUG */
3e4b811998-10-16Henrik Grubbström (Grubba)  if (_cache_full) { return; }
c084262000-02-04Henrik Grubbström (Grubba)  foreach(joined_modules, object|mapping|program o) {
3e4b811998-10-16Henrik Grubbström (Grubba)  foreach(indices(o), string index) { if (zero_type(cache[index])) { `[](index); } } } _cache_full = 1; } array(string) _indices() { fill_cache(); return indices(cache); } array(mixed) _values() { fill_cache(); return values(cache); }
94257b1998-10-16Henrik Grubbström (Grubba) };
1792a71998-04-10Henrik Grubbström (Grubba) // Variables mustn't be static to allow for replace_master(). // /grubba 1998-04-10 mapping(string:mixed) fc=([]);
ca2b071998-03-28Henrik Grubbström (Grubba)  object findmodule(string fullname) {
afa1292000-02-19Martin Nilsson  array stat;
ca2b071998-03-28Henrik Grubbström (Grubba)  object o; if(!zero_type(o=fc[fullname])) { return o; }
61a4242000-08-27Mirar (Pontus Hagland)  if(Stat stat=master_file_stat(fakeroot(fullname+".pmod")))
ca2b071998-03-28Henrik Grubbström (Grubba)  { if(stat[1]==-2)
cc2c071998-04-19Fredrik Hübinette (Hubbe)  return fc[fullname]=dirnode(fullname+".pmod");
ca2b071998-03-28Henrik Grubbström (Grubba)  } if(o=low_cast_to_object(fullname+".pmod","/.")) return fc[fullname]=o; #if constant(load_module)
26f3da2000-07-11Fredrik Hübinette (Hubbe)  if(master_file_stat(fakeroot(fullname+".so")))
ca2b071998-03-28Henrik Grubbström (Grubba)  return fc[fullname]=low_cast_to_object(fullname,"/."); #endif return fc[fullname]=UNDEFINED; }
10e16f1999-11-04Henrik Grubbström (Grubba) mixed handle_import(string what, string|void current_file, object|void handler)
ca2b071998-03-28Henrik Grubbström (Grubba) {
afa1292000-02-19Martin Nilsson  array(string) tmp; string path;
ca2b071998-03-28Henrik Grubbström (Grubba)  if(current_file) {
471ed91998-04-24Fredrik Hübinette (Hubbe)  tmp=EXPLODE_PATH(current_file);
cc2c071998-04-19Fredrik Hübinette (Hubbe)  tmp[-1]=what;
ca2b071998-03-28Henrik Grubbström (Grubba)  path=combine_path_with_cwd( tmp*"/"); }
cc2c071998-04-19Fredrik Hübinette (Hubbe)  return fc[path]=dirnode(path); }
a20af62000-09-26Fredrik Hübinette (Hubbe)  multiset no_resolv = (<>); class CompatResolver
cc2c071998-04-19Fredrik Hübinette (Hubbe) {
a20af62000-09-26Fredrik Hübinette (Hubbe)  array(string) pike_include_path=({}); array(string) pike_module_path=({}); array(string) pike_program_path=({}); int want_warnings = PIKE_WARNINGS; string ver; void create(mixed v) { ver=(string)v; } void add_include_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_include_path-=({tmp}); pike_include_path=({tmp})+pike_include_path; } void remove_include_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_include_path-=({tmp}); } void add_module_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_module_path-=({tmp}); pike_module_path=({tmp})+pike_module_path; } void remove_module_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_module_path-=({tmp}); } void add_program_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_program_path-=({tmp}); pike_program_path=({tmp})+pike_program_path; } void remove_program_path(string tmp) { tmp=normalize_path(combine_path_with_cwd(tmp)); pike_program_path-=({tmp}); } mapping get_default_module() { /* This is an ugly kluge to avoid an infinite recursion. * The infinite recursion occurs because this function is * called for every file when the compat_major/minor is set. * This kluge could cause problems with threads if the * compiler was threaded. -Hubbe */ int saved_compat_minor=compat_minor; int saved_compat_major=compat_major; compat_minor=-1; compat_major=-1; mixed x; mixed err =catch { if(x=resolv("__default.all_constants")) x=x(); }; compat_major=saved_compat_major; compat_minor=saved_compat_minor; if(err) throw(err); return x; } mixed resolv_base(string identifier, string|void current_file) { array(mixed) tmp = ({}); foreach(pike_module_path, string path) { string file=combine_path(path,identifier); if(mixed ret=findmodule(file)) { if ((objectp(ret)) && (ret->is_resolv_dirnode || ret->is_resolv_joinnode)) { if (mixed new_ret = ret->_module_value) { ret = new_ret; } tmp += ({ ret }); } else { if (mixed new_ret = ret->_module_value) { ret = new_ret; } if (!sizeof(tmp)) { return ret; } else { // Ignore werror(sprintf("Ignoring file %O: %t for identifier %O\n", file, ret, identifier)); continue; } } }
8b307e1998-10-17Henrik Grubbström (Grubba)  }
a20af62000-09-26Fredrik Hübinette (Hubbe)  if (sizeof(tmp)) { if (sizeof(tmp) == 1) { return(tmp[0]);
8b307e1998-10-17Henrik Grubbström (Grubba)  }
a20af62000-09-26Fredrik Hübinette (Hubbe)  return joinnode(tmp);
ca2b071998-03-28Henrik Grubbström (Grubba)  }
a20af62000-09-26Fredrik Hübinette (Hubbe)  return UNDEFINED;
94257b1998-10-16Henrik Grubbström (Grubba)  }
a20af62000-09-26Fredrik Hübinette (Hubbe)  mapping resolv_cache = set_weak_flag( ([]), 1 ); mixed resolv(string identifier, string|void current_file) { if( no_resolv[ identifier ] ) return UNDEFINED; mixed ret; string id=identifier+":"+(current_file ? dirname(current_file) : "-"); if( !zero_type (ret = resolv_cache[id]) ) return ret == ZERO_TYPE ? UNDEFINED : resolv_cache[id]; array(string) tmp=identifier/"."; ret=resolv_base(tmp[0]); foreach(tmp[1..],string index) ret=ret[index]; resolv_cache[id] = zero_type (ret) ? ZERO_TYPE : ret; return ret; } /* This function is called whenever an #include directive is encountered * it receives the argument for #include and should return the file name * of the file to include */ string handle_include(string f, string current_file, int local_include) { array(string) tmp; string path; if(local_include) { tmp=EXPLODE_PATH(current_file); tmp[-1]=f; path=combine_path_with_cwd(tmp*"/"); } else { foreach(pike_include_path, path) { path=combine_path(path,f); if(master_file_stat(fakeroot(path))) break; else path=0; } } return path; } string read_include(string f) { AUTORELOAD_CHECK_FILE(f) return master_read_file(f); } string _sprintf() { return sprintf("CompatResolver(%s)",ver);
94257b1998-10-16Henrik Grubbström (Grubba)  }
7c11f41999-10-04Fredrik Hübinette (Hubbe) }
a20af62000-09-26Fredrik Hübinette (Hubbe) inherit CompatResolver;
bfa62b1998-04-30Henrik Grubbström (Grubba) // These are useful if you want to start other Pike processes // with the same options as this one was started with. string _pike_file_name;
ac51841998-04-29Henrik Grubbström (Grubba) string _master_file_name;
53a32a2000-06-04Francesco Chemolli //flag. Gets set to 1 if we're in async-mode (script->main() returned <0) private int _async=0; int asyncp() { return _async; }
ca2b071998-03-28Henrik Grubbström (Grubba) /* This function is called when all the driver is done with all setup * of modules, efuns, tables etc. etc. and is ready to start executing * _real_ programs. It receives the arguments not meant for the driver * and an array containing the environment variables on the same form as * a C program receives them. */
afa1292000-02-19Martin Nilsson void _main(array(string) orig_argv, array(string) env)
ca2b071998-03-28Henrik Grubbström (Grubba) {
afa1292000-02-19Martin Nilsson  array(string) argv=copy_value(orig_argv);
862fb41998-04-05Fredrik Hübinette (Hubbe)  int i,debug,trace;
ca2b071998-03-28Henrik Grubbström (Grubba)  object tmp; string a,b;
afa1292000-02-19Martin Nilsson  array q;
ca2b071998-03-28Henrik Grubbström (Grubba) 
bfa62b1998-04-30Henrik Grubbström (Grubba)  _pike_file_name = orig_argv[0];
d854161999-04-08Fredrik Hübinette (Hubbe)  foreach(env,a) { if(sscanf(a,"%s=%s",a,b)) { if(a=="") // Special hack for NT { sscanf(b,"%s=%s",a,b); a="="+a; } environment[a]=b;
d7741a1999-08-06Fredrik Hübinette (Hubbe)  }else{ werror("Broken environment var %s\n",a); }
d854161999-04-08Fredrik Hübinette (Hubbe)  }
ca2b071998-03-28Henrik Grubbström (Grubba) 
624e851999-06-02Marcus Comstedt 
e90a8b1999-06-01Mirar (Pontus Hagland) #ifndef NOT_INSTALLED q=(getenv("PIKE_INCLUDE_PATH")||"")/":"-({""}); for(i=sizeof(q)-1;i>=0;i--) add_include_path(q[i]);
ca2b071998-03-28Henrik Grubbström (Grubba) 
e90a8b1999-06-01Mirar (Pontus Hagland)  q=(getenv("PIKE_PROGRAM_PATH")||"")/":"-({""}); for(i=sizeof(q)-1;i>=0;i--) add_program_path(q[i]);
ca2b071998-03-28Henrik Grubbström (Grubba) 
e90a8b1999-06-01Mirar (Pontus Hagland)  q=(getenv("PIKE_MODULE_PATH")||"")/":"-({""}); for(i=sizeof(q)-1;i>=0;i--) add_module_path(q[i]); #endif
ca2b071998-03-28Henrik Grubbström (Grubba)  if(sizeof(argv)>1 && sizeof(argv[1]) && argv[1][0]=='-') { tmp=resolv("Getopt");
a7a45a1998-05-11Henrik Grubbström (Grubba)  if (!tmp) { werror("master.pike: Couldn't resolv Getopt module.\n" "Is your PIKE_MODULE_PATH environment variable set correctly?\n"); exit(1); }
ca2b071998-03-28Henrik Grubbström (Grubba)  q=tmp->find_all_options(argv,({
a20af62000-09-26Fredrik Hübinette (Hubbe)  ({"compat_version",tmp->HAS_ARG,({"-V","--compat"})}),
ca2b071998-03-28Henrik Grubbström (Grubba)  ({"version",tmp->NO_ARG,({"-v","--version"})}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  ({"help",tmp->NO_ARG,({"-h","--help"})}), ({"execute",tmp->HAS_ARG,({"-e","--execute"})}),
3d14462000-09-24Per Hedbor  ({"debug_without",tmp->HAS_ARG,({"--debug-without"})}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  ({"preprocess",tmp->HAS_ARG,({"-E","--preprocess"})}), ({"modpath",tmp->HAS_ARG,({"-M","--module-path"})}), ({"ipath",tmp->HAS_ARG,({"-I","--include-path"})}), ({"ppath",tmp->HAS_ARG,({"-P","--program-path"})}),
2ea8261998-05-12Martin Stjernholm  ({"showpaths",tmp->NO_ARG,"--show-paths"}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  ({"warnings",tmp->NO_ARG,({"-w","--warnings"})}),
098c8a2000-03-30Henrik Grubbström (Grubba)  ({"nowarnings",tmp->NO_ARG,({"-W", "--woff", "--no-warnings"})}),
bec57d1999-09-06Fredrik Hübinette (Hubbe) #ifdef PIKE_AUTORELOAD ({"autoreload",tmp->NO_ARG,({"--autoreload"})}), #endif
ac51841998-04-29Henrik Grubbström (Grubba)  ({"master",tmp->HAS_ARG,"-m"}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  ({"compiler_trace",tmp->NO_ARG,"--compiler-trace"}),
e27a5c1999-11-19Henrik Grubbström (Grubba)  ({"optimizer_debug",tmp->MAY_HAVE_ARG,"--optimizer-debug"}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  ({"debug",tmp->MAY_HAVE_ARG,"--debug",0,1}), ({"trace",tmp->MAY_HAVE_ARG,"--trace",0,1}),
e26bdd1999-12-13Per Hedbor  ({"ignore",tmp->MAY_HAVE_ARG,"-Dqdatplr",0,1}),
ac51841998-04-29Henrik Grubbström (Grubba)  ({"ignore",tmp->HAS_ARG,"-s"}),
c5cc2d1998-04-29Henrik Grubbström (Grubba)  }), 1);
ca2b071998-03-28Henrik Grubbström (Grubba)  /* Parse -M and -I backwards */ for(i=sizeof(q)-1;i>=0;i--) { switch(q[i][0]) {
a20af62000-09-26Fredrik Hübinette (Hubbe)  case "compat_version": sscanf(q[i][1],"%d.%d",compat_major,compat_minor); break;
bec57d1999-09-06Fredrik Hübinette (Hubbe) #ifdef PIKE_AUTORELOAD case "autoreload": autoreload_on++; #endif
3d14462000-09-24Per Hedbor  case "debug_without": foreach( q[i][1]/",", string feature ) { switch( feature ) { case "ttf": no_resolv[ "_Image_TTF" ] = 1; break; case "zlib": no_resolv[ "Gz" ] = 1; break; case "unisys": no_resolv[ "_Image_GIF" ] = 1; no_resolv[ "_Image_TIFF" ] = 1; break; case "threads": // not really 100% correct, but good enough for most things. no_resolv[ "Thread" ] = 1; add_constant( "thread_create", ([])[0] ); break; default: no_resolv[ feature ] = 1; break; } } break;
c5cc2d1998-04-29Henrik Grubbström (Grubba)  case "debug": debug+=(int)q[i][1]; break;
862fb41998-04-05Fredrik Hübinette (Hubbe) 
c5cc2d1998-04-29Henrik Grubbström (Grubba) #if constant(_compiler_trace) case "compiler_trace": _compiler_trace(1); break; #endif /* constant(_compiler_trace) */
e27a5c1999-11-19Henrik Grubbström (Grubba) #if constant(_optimizer_debug) case "optimizer_debug": _optimizer_debug((int)q[i][1]); break; #endif /* constant(_optimizer_debug) */
c5cc2d1998-04-29Henrik Grubbström (Grubba)  case "trace": trace+=(int)q[i][1]; break;
862fb41998-04-05Fredrik Hübinette (Hubbe) 
ca2b071998-03-28Henrik Grubbström (Grubba)  case "modpath": add_module_path(q[i][1]); break; case "ipath": add_include_path(q[i][1]); break; case "ppath": add_program_path(q[i][1]); break;
c5cc2d1998-04-29Henrik Grubbström (Grubba)  case "warnings":
ca2b071998-03-28Henrik Grubbström (Grubba)  want_warnings++; break;
ac51841998-04-29Henrik Grubbström (Grubba) 
098c8a2000-03-30Henrik Grubbström (Grubba)  case "no-warnings": want_warnings--; break;
ac51841998-04-29Henrik Grubbström (Grubba)  case "master": _master_file_name = q[i][1]; break;
ca2b071998-03-28Henrik Grubbström (Grubba)  } }
afa1292000-02-19Martin Nilsson  foreach(q, array opts)
ca2b071998-03-28Henrik Grubbström (Grubba)  { switch(opts[0]) { case "version":
bbf4702000-04-10Henrik Grubbström (Grubba)  werror(version() + " Copyright © 1994-2000 Fredrik Hübinette\n"
ca2b071998-03-28Henrik Grubbström (Grubba)  "Pike comes with ABSOLUTELY NO WARRANTY; This is free software and you are\n" "welcome to redistribute it under certain conditions; Read the files\n" "COPYING and DISCLAIMER in the Pike distribution for more details.\n"); exit(0); case "help": werror("Usage: pike [-driver options] script [script arguments]\n" "Driver options include:\n" " -I --include-path=<p>: Add <p> to the include path\n" " -M --module-path=<p> : Add <p> to the module path\n" " -P --program-path=<p>: Add <p> to the program path\n" " -e --execute=<cmd> : Run the given command instead of a script.\n" " -h --help : see this message\n" " -v --version : See what version of pike you have.\n"
2ea8261998-05-12Martin Stjernholm  " --show-paths : See the paths and master that pike uses.\n"
ca2b071998-03-28Henrik Grubbström (Grubba)  " -s# : Set stack size\n" " -m <file> : Use <file> as master object.\n" " -d -d# : Increase debug (# is how much)\n" " -t -t# : Increase trace level\n" ); exit(0);
2ea8261998-05-12Martin Stjernholm  case "showpaths": werror("Include path : " + pike_include_path*"\n" " " + "\n" "Module path : " + pike_module_path*"\n" " " + "\n" "Program path : " + pike_program_path*"\n" " " + "\n"
3692711999-02-05Martin Stjernholm  "Master file : " + (_master_file_name || __FILE__) + "\n");
2ea8261998-05-12Martin Stjernholm  exit(0);
ca2b071998-03-28Henrik Grubbström (Grubba)  case "execute":
9339fc2000-01-09Fredrik Hübinette (Hubbe)  random_seed(time() + (getpid() * 0x11111111));
a20af62000-09-26Fredrik Hübinette (Hubbe)  compile_string("mixed create(){"+opts[1]+";}")();
ca2b071998-03-28Henrik Grubbström (Grubba)  exit(0);
fcf7281998-04-28Fredrik Hübinette (Hubbe) 
c5cc2d1998-04-29Henrik Grubbström (Grubba)  case "preprocess":
d8a6fc2000-03-25Fredrik Hübinette (Hubbe)  _static_modules.files()->_stdout->write(cpp(master_read_file(opts[1]), opts[1]));
c5cc2d1998-04-29Henrik Grubbström (Grubba)  exit(0);
ca2b071998-03-28Henrik Grubbström (Grubba)  } }
caa3221998-04-15Henrik Grubbström (Grubba)  argv = tmp->get_args(argv,1);
ca2b071998-03-28Henrik Grubbström (Grubba)  }
9339fc2000-01-09Fredrik Hübinette (Hubbe)  random_seed(time() + (getpid() * 0x11111111));
ca2b071998-03-28Henrik Grubbström (Grubba)  if(sizeof(argv)==1) {
caa3221998-04-15Henrik Grubbström (Grubba)  /* Attempt to resolv Tools.Hilfe.StdinHilfe */ tmp = resolv("Tools"); if (!tmp) { werror("Couldn't find Tools.\n"); exit(1);
ca2b071998-03-28Henrik Grubbström (Grubba)  }
caa3221998-04-15Henrik Grubbström (Grubba)  tmp = tmp["Hilfe"]; if (!tmp) { werror("Couldn't find Hilfe.\n"); exit(1); } tmp->StdinHilfe(); exit(0); } else {
ca2b071998-03-28Henrik Grubbström (Grubba)  argv=argv[1..]; }
471ed91998-04-24Fredrik Hübinette (Hubbe)  argv[0]=combine_path_with_cwd(argv[0]);
ca2b071998-03-28Henrik Grubbström (Grubba) 
586d1c2000-09-04Fredrik Hübinette (Hubbe)  program prog;
34fb3d1998-10-31Henrik Grubbström (Grubba)  mixed err = catch {
586d1c2000-09-04Fredrik Hübinette (Hubbe)  prog=(program)argv[0];
34fb3d1998-10-31Henrik Grubbström (Grubba)  }; if (err) { werror(sprintf("Pike: Failed to compile script:\n" "%s\n", stringp(err[0])?err[0]:describe_backtrace(err))); exit(1); } // FIXME: Isn't the following code dead?
586d1c2000-09-04Fredrik Hübinette (Hubbe)  if(!prog)
ca2b071998-03-28Henrik Grubbström (Grubba)  {
62962b1999-06-01Mirar (Pontus Hagland)  werror("Pike: Couldn't find script to execute\n(%O)\n",argv[0]);
ca2b071998-03-28Henrik Grubbström (Grubba)  exit(1); }
586d1c2000-09-04Fredrik Hübinette (Hubbe)  object script=prog();
ca2b071998-03-28Henrik Grubbström (Grubba) 
862fb41998-04-05Fredrik Hübinette (Hubbe) #if constant(_debug) if(debug) _debug(debug); #endif
ca2b071998-03-28Henrik Grubbström (Grubba)  if(!script->main) { werror("Error: "+argv[0]+" has no main().\n"); exit(1); }
fcf7281998-04-28Fredrik Hübinette (Hubbe)  if(trace) predef::trace(trace);
ca2b071998-03-28Henrik Grubbström (Grubba)  i=script->main(sizeof(argv),argv,env); if(i >=0) exit(i);
53a32a2000-06-04Francesco Chemolli  _async=1;
ca2b071998-03-28Henrik Grubbström (Grubba) }
01d3c91999-11-04Henrik Grubbström (Grubba) #if constant(thread_local) object inhibit_compile_errors = thread_local(); void set_inhibit_compile_errors(mixed f) { inhibit_compile_errors->set(f); }
71d9951999-11-29Henrik Grubbström (Grubba)  mixed get_inhibit_compile_errors() {
c2eb4a1999-11-29David Hedbor  return inhibit_compile_errors->get();
71d9951999-11-29Henrik Grubbström (Grubba) }
01d3c91999-11-04Henrik Grubbström (Grubba) #else /* !constant(thread_local) */
ca2b071998-03-28Henrik Grubbström (Grubba) mixed inhibit_compile_errors; void set_inhibit_compile_errors(mixed f) { inhibit_compile_errors=f; }
71d9951999-11-29Henrik Grubbström (Grubba)  mixed get_inhibit_compile_errors() {
c2eb4a1999-11-29David Hedbor  return inhibit_compile_errors;
71d9951999-11-29Henrik Grubbström (Grubba) }
01d3c91999-11-04Henrik Grubbström (Grubba) #endif /* constant(thread_local) */
ca2b071998-03-28Henrik Grubbström (Grubba)  string trim_file_name(string s) {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  if(getenv("LONG_PIKE_ERRORS")) return s;
471ed91998-04-24Fredrik Hübinette (Hubbe)  if(getenv("SHORT_PIKE_ERRORS")) return BASENAME(s);
df2c632000-08-02Henrik Grubbström (Grubba)  /* getcwd() can fail, but since this is called from handle_error(), * we don't want to fail, so we don't care about that. */ catch { string cwd=getcwd(); if (sizeof(cwd) && (cwd[-1] != '/')) { cwd += "/"; } if(s[..sizeof(cwd)-1]==cwd) return s[sizeof(cwd)..]; };
ca2b071998-03-28Henrik Grubbström (Grubba)  return s; } /*
c084262000-02-04Henrik Grubbström (Grubba)  * This function is called whenever a compiling error occurs.
ca2b071998-03-28Henrik Grubbström (Grubba)  * Nothing strange about it. * Note that previous_object cannot be trusted in ths function, because * the compiler calls this function. */ void compile_error(string file,int line,string err) {
01d3c91999-11-04Henrik Grubbström (Grubba)  mixed val;
3112422000-03-27Per Hedbor  if(! (val = get_inhibit_compile_errors() ))
ca2b071998-03-28Henrik Grubbström (Grubba)  {
58f1af1999-12-29Martin Stjernholm  werror(sprintf("%s:%s:%s\n",trim_file_name(file), line?(string)line:"-",err));
ca2b071998-03-28Henrik Grubbström (Grubba)  }
01d3c91999-11-04Henrik Grubbström (Grubba)  else if(objectp(val) || programp(val) || functionp(val))
ca2b071998-03-28Henrik Grubbström (Grubba)  {
01d3c91999-11-04Henrik Grubbström (Grubba)  if (objectp(val) && val->compile_error) { val->compile_error(file, line, err); } else {
3112422000-03-27Per Hedbor  val(file, line, err);
01d3c91999-11-04Henrik Grubbström (Grubba)  }
ca2b071998-03-28Henrik Grubbström (Grubba)  } } /*
c084262000-02-04Henrik Grubbström (Grubba)  * This function is called whenever a compiling warning occurs.
ca2b071998-03-28Henrik Grubbström (Grubba)  * Nothing strange about it. * Note that previous_object cannot be trusted in ths function, because * the compiler calls this function. */ void compile_warning(string file,int line,string err) {
01d3c91999-11-04Henrik Grubbström (Grubba)  mixed val;
3112422000-03-27Per Hedbor  if(!(val = get_inhibit_compile_errors() ))
ca2b071998-03-28Henrik Grubbström (Grubba)  { if(want_warnings)
58f1af1999-12-29Martin Stjernholm  werror(sprintf("%s:%s: Warning: %s\n",trim_file_name(file), line?(string)line:"-",err));
01d3c91999-11-04Henrik Grubbström (Grubba)  } else if (objectp(val) && val->compile_warning) { val->compile_warning(file, line, err);
ca2b071998-03-28Henrik Grubbström (Grubba)  } }
8f23062000-06-09Martin Stjernholm /* * Called for every runtime warning. The first argument identifies * where the warning comes from, the second identifies the specific * message, and the rest depends on that. See code below for currently * implemented warnings. */ void runtime_warning (string where, string what, mixed... args) { if (want_warnings) switch (where + "." + what) { case "gc.bad_cycle": // args[0] is an array containing the objects in the cycle // which aren't destructed and have destroy() functions. werror ("GC warning: Garbing cycle where destroy() will be called " "in arbitrary order:\n%{ %s\n%}", map (args[0], describe_object)); break; default: werror ("%s warning: %s %O\n", capitalize (where), what, args); } }
ca2b071998-03-28Henrik Grubbström (Grubba) 
f4f08d1999-02-26Henrik Grubbström (Grubba) static mixed _charset_mod; /* This function is called by cpp() when it wants to do * character code conversion. */ string decode_charset(string data, string charset) {
db25e61999-02-26Henrik Grubbström (Grubba)  // werror(sprintf("decode_charset(%O, %O)\n", data, charset));
f4f08d1999-02-26Henrik Grubbström (Grubba)  if (!_charset_mod) { mixed mod = resolv("Locale"); _charset_mod = mod && mod["Charset"]; if (!_charset_mod) { compile_warning("-", 0, "No Locale.Charset module!"); return 0; } } object decoder; catch { decoder = _charset_mod->decoder(charset); }; if (!decoder) { compile_warning("-", 0, sprintf("Unknown charset %O!", charset)); return 0; } return decoder->feed(data)->drain(); }
ca2b071998-03-28Henrik Grubbström (Grubba) 
da0a822000-08-29Martin Stjernholm class Describer
ca2b071998-03-28Henrik Grubbström (Grubba) {
da0a822000-08-29Martin Stjernholm  int clipped=0; int canclip=0; mapping(mixed:int|string) ident = ([]); int identcount = 0; void identify_parts (mixed stuff) { if (arrayp (stuff)) { if (!ident[stuff]++) foreach (stuff, mixed elem) identify_parts (elem); } else if (multisetp (stuff)) { if (!ident[stuff]++) foreach (indices (stuff), mixed elem) identify_parts (elem); } else if (mappingp (stuff)) { if (!ident[stuff]++) foreach (indices (stuff), mixed elem) identify_parts (elem), identify_parts (stuff[elem]); }
2602b82000-08-29Martin Stjernholm  else if (objectp (stuff) || functionp (stuff) || programp (stuff))
da0a822000-08-29Martin Stjernholm  ident[stuff]++; }
2602b82000-08-29Martin Stjernholm  string describe_string (string m, int maxlen) { canclip++; if(sizeof(m) < maxlen) { string t = sprintf("%O", m); if (sizeof(t) < (maxlen + 2)) { return t; } t = 0; } clipped++; if(maxlen>10) { return sprintf("%O+[%d]",m[..maxlen-5],sizeof(m)-(maxlen-5)); }else{ return "string["+sizeof(m)+"]"; } } string describe_array (array m, int maxlen) { if(!sizeof(m)) return "({})"; else { if(maxlen<5) { clipped++; return "array["+sizeof(m)+"]"; } else { canclip++; return "({" + describe_comma_list(m,maxlen-2) +"})"; } } } string describe_mapping (mapping m, int maxlen) { if(!sizeof(m)) return "([])"; else return "mapping["+sizeof(m)+"]"; } string describe_multiset (multiset m, int maxlen) { if(!sizeof(m)) return "(<>)"; else return "multiset["+sizeof(m)+"]"; }
da0a822000-08-29Martin Stjernholm  string describe (mixed m, int maxlen)
ca2b071998-03-28Henrik Grubbström (Grubba)  {
da0a822000-08-29Martin Stjernholm  if (stringp (ident[m])) return ident[m]; else if (intp (ident[m]) && ident[m] > 1) ident[m] = "@" + identcount++; string res, typ; if (catch (typ=sprintf("%t",m))) typ = "object"; // Object with a broken _sprintf(), probably. switch(typ) { case "int": case "float": return (string)m; case "string":
2602b82000-08-29Martin Stjernholm  return describe_string (m, maxlen);
da0a822000-08-29Martin Stjernholm  case "array":
2602b82000-08-29Martin Stjernholm  res = describe_array (m, maxlen);
da0a822000-08-29Martin Stjernholm  break; case "mapping":
2602b82000-08-29Martin Stjernholm  res = describe_mapping (m, maxlen);
da0a822000-08-29Martin Stjernholm  break; case "multiset":
2602b82000-08-29Martin Stjernholm  res = describe_multiset (m, maxlen);
da0a822000-08-29Martin Stjernholm  break; case "function":
2602b82000-08-29Martin Stjernholm  if (string tmp=describe_function(m)) res = tmp; else res = typ; break;
da0a822000-08-29Martin Stjernholm  case "program":
2602b82000-08-29Martin Stjernholm  if(string tmp=describe_program(m)) res = tmp; else res = typ; break;
da0a822000-08-29Martin Stjernholm  default: if (objectp(m)) if(string tmp=describe_object(m)) { res = tmp; break; }
2602b82000-08-29Martin Stjernholm  res = typ;
da0a822000-08-29Martin Stjernholm  }
ca2b071998-03-28Henrik Grubbström (Grubba) 
da0a822000-08-29Martin Stjernholm  if (stringp (ident[m])) return ident[m] + "=" + res; return res; }
e8ebc01999-08-27Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  string describe_comma_list(array x, int maxlen) { string ret="";
e8ebc01999-08-27Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  if(!sizeof(x)) return ""; if(maxlen<0) return ",,,"+sizeof(x);
5e09161999-10-15Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  int clip=min(maxlen/2,sizeof(x)); int len=maxlen; int done=0;
ba20b11999-10-15Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  // int loopcount=0;
ba20b11999-10-15Fredrik Hübinette (Hubbe)  while(1) {
da0a822000-08-29Martin Stjernholm  // if(loopcount>10000) werror("len=%d\n",len); array(string) z=allocate(clip); array(int) isclipped=allocate(clip); array(int) clippable=allocate(clip); for(int e=0;e<clip;e++)
ba20b11999-10-15Fredrik Hübinette (Hubbe)  {
da0a822000-08-29Martin Stjernholm  clipped=0; canclip=0; z[e]=describe(x[e],len); isclipped[e]=clipped; clippable[e]=canclip;
ba20b11999-10-15Fredrik Hübinette (Hubbe)  } while(1) {
da0a822000-08-29Martin Stjernholm  // if(loopcount>10000) werror("clip=%d maxlen=%d\n",clip,maxlen); string ret = z[..clip-1]*","; // if(loopcount>10000) werror("sizeof(ret)=%d z=%O isclipped=%O done=%d\n",sizeof(ret),z[..clip-1],isclipped[..clip-1],done); if(done || sizeof(ret)<=maxlen+1) { int tmp=sizeof(x)-clip-1; // if(loopcount>10000) werror("CLIPPED::::: %O\n",isclipped); clipped=`+(0,@isclipped); if(tmp>=0) { clipped++; ret+=",,,"+tmp; } canclip++; return ret; } int last_newlen=len; int newlen; int clipsuggest; while(1) { // if(loopcount++ > 20000) return ""; // if(!(loopcount & 0xfff)) werror("GNORK\n"); int smallsize=0; int num_large=0; clipsuggest=0;
ba20b11999-10-15Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  for(int e=0;e<clip;e++)
ba20b11999-10-15Fredrik Hübinette (Hubbe)  {
da0a822000-08-29Martin Stjernholm  // if(loopcount>10000) werror("sizeof(z[%d])=%d len=%d\n",e,sizeof(z[e]),len);
ba20b11999-10-15Fredrik Hübinette (Hubbe) 
5e09161999-10-15Fredrik Hübinette (Hubbe)  if((sizeof(z[e])>=last_newlen || isclipped[e]) && clippable[e])
ba20b11999-10-15Fredrik Hübinette (Hubbe)  num_large++; else smallsize+=sizeof(z[e]); if(num_large * 15 + smallsize < maxlen) clipsuggest=e+1; }
da0a822000-08-29Martin Stjernholm  // if(loopcount>10000) werror("num_large=%d maxlen=%d smallsize=%d clippsuggest=%d\n",num_large,maxlen,smallsize,clipsuggest); newlen=num_large ? (maxlen-smallsize)/num_large : 0;
ba20b11999-10-15Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  // if(loopcount>10000) werror("newlen=%d\n",newlen);
ba20b11999-10-15Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  if(newlen<8 || newlen >= last_newlen) break; last_newlen=newlen; // if(loopcount>10000) werror("len decreased, retrying.\n"); }
e8ebc01999-08-27Fredrik Hübinette (Hubbe) 
da0a822000-08-29Martin Stjernholm  if(newlen < 8 && clip) { clip-= (clip/4) || 1; if(clip > clipsuggest) clip=clipsuggest; // if(loopcount>10000) werror("clip decreased, retrying.\n"); }else{ len=newlen; done++; break; }
ba20b11999-10-15Fredrik Hübinette (Hubbe)  } }
da0a822000-08-29Martin Stjernholm  return ret; }
e8ebc01999-08-27Fredrik Hübinette (Hubbe) }
bec57d1999-09-06Fredrik Hübinette (Hubbe) string describe_object(object o) { string s; if(!o) return 0;
80e50f2000-03-23Martin Stjernholm  if (!catch (s = sprintf("%O",o)) && s != "object") return s;
bec57d1999-09-06Fredrik Hübinette (Hubbe)  if(( s=describe_program(object_program(o)) )) return s+"()"; return 0; }
62e87b1998-04-14Fredrik Hübinette (Hubbe) string describe_program(program p) { string s; if(!p) return 0; if(s=search(programs,p)) { if(sscanf(reverse(s),"%s.%s",string ext,string rest) && ext=="domp")
471ed91998-04-24Fredrik Hübinette (Hubbe)  return EXPLODE_PATH(reverse(rest))[-1];
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  return trim_file_name(s);
62e87b1998-04-14Fredrik Hübinette (Hubbe)  }
337ad81998-04-15Fredrik Hübinette (Hubbe)  if(functionp(p)) if(mixed tmp=function_object(p)) if(s=describe_program(object_program(tmp))) return s+"."+function_name(p);
bec57d1999-09-06Fredrik Hübinette (Hubbe)  if(s=_static_modules.Builtin()->program_defined(p)) return EXPLODE_PATH(s)[-1];
62e87b1998-04-14Fredrik Hübinette (Hubbe)  return 0; }
2602b82000-08-29Martin Stjernholm string describe_function (function f) { if (!f) return 0; string name; if(string s=search(programs,f)) { if(sscanf(reverse(s),"%s.%s",string ext,string rest) && ext=="domp") name = EXPLODE_PATH(reverse(rest))[-1]; else name = trim_file_name(s); } else if (catch (name = function_name (f))) name = "function"; if(object o=function_object(f)) { string s; if (!catch (s = sprintf("%O",o)) && s != "object") return s+"->"+name; } return name; }
ca2b071998-03-28Henrik Grubbström (Grubba) /* It is possible that this should be a real efun, * it is currently used by handle_error to convert a backtrace to a * readable message. */
ba20b11999-10-15Fredrik Hübinette (Hubbe) string describe_backtrace(mixed trace, void|int linewidth)
ca2b071998-03-28Henrik Grubbström (Grubba) { int e; string ret;
d4fd0a1999-12-06Henrik Grubbström (Grubba)  int backtrace_len=((int)getenv("PIKE_BACKTRACE_LEN")) || bt_max_string_len;
ca2b071998-03-28Henrik Grubbström (Grubba) 
ba20b11999-10-15Fredrik Hübinette (Hubbe)  if(!linewidth) { linewidth=99999; catch { linewidth=_static_modules.files()->_stdin->tcgetattr()->columns; };
fe8fb32000-01-15Fredrik Hübinette (Hubbe)  if(linewidth<10) linewidth=99999;
ba20b11999-10-15Fredrik Hübinette (Hubbe)  }
f417dd1999-03-19Fredrik Hübinette (Hubbe)  if((arrayp(trace) && sizeof(trace)==2 && stringp(trace[0])) || (objectp(trace) && trace->is_generic_error))
ca2b071998-03-28Henrik Grubbström (Grubba)  {
a232721999-10-06Henrik Grubbström (Grubba)  if (catch {
9798481999-12-06Henrik Grubbström (Grubba)  ret = trace[0] || "No error message!\n";
a232721999-10-06Henrik Grubbström (Grubba)  trace = trace[1]; }) { return "Error indexing backtrace!\n"; }
ca2b071998-03-28Henrik Grubbström (Grubba)  }else{ ret=""; } if(!arrayp(trace)) { ret+="No backtrace.\n"; }else{
da0a822000-08-29Martin Stjernholm  Describer desc = Describer(); desc->identify_parts (trace);
a232721999-10-06Henrik Grubbström (Grubba)  for(e = sizeof(trace)-1; e>=0; e--)
ca2b071998-03-28Henrik Grubbström (Grubba)  { mixed tmp; string row;
e118831999-12-22Per Hedbor  if( arrayp(trace[e]) && (sizeof(trace[e]) > 2) && (trace[e][2] == _main) && (sizeof(trace)>1) ) continue;
ba20b11999-10-15Fredrik Hübinette (Hubbe)  if (mixed err=catch {
a232721999-10-06Henrik Grubbström (Grubba)  tmp = trace[e]; if(stringp(tmp))
ca2b071998-03-28Henrik Grubbström (Grubba)  {
ba20b11999-10-15Fredrik Hübinette (Hubbe)  row=tmp;
ca2b071998-03-28Henrik Grubbström (Grubba)  }
a232721999-10-06Henrik Grubbström (Grubba)  else if(arrayp(tmp))
ca2b071998-03-28Henrik Grubbström (Grubba)  {
ba20b11999-10-15Fredrik Hübinette (Hubbe)  string pos;
dbe79a1999-12-07Henrik Grubbström (Grubba)  if(sizeof(tmp)>=2 && stringp(tmp[0])) { if (intp(tmp[1])) { pos=trim_file_name(tmp[0])+":"+tmp[1]; } else { pos = sprintf("%s:Bad line %t", trim_file_name(tmp[0]), tmp[1]); }
a232721999-10-06Henrik Grubbström (Grubba)  }else{ mixed desc="Unknown program"; if(sizeof(tmp)>=3 && functionp(tmp[2])) {
e118831999-12-22Per Hedbor  catch {
a232721999-10-06Henrik Grubbström (Grubba)  if(mixed tmp=function_object(tmp[2])) if(tmp=object_program(tmp)) if(tmp=describe_program(tmp)) desc=tmp; }; }
ba20b11999-10-15Fredrik Hübinette (Hubbe)  pos=desc; } string data; if(sizeof(tmp)>=3) {
dfca1f2000-08-22Martin Stjernholm  if(functionp(tmp[2])) {
2602b82000-08-29Martin Stjernholm  data = describe_function (tmp[2]);
dfca1f2000-08-22Martin Stjernholm  }
ba20b11999-10-15Fredrik Hübinette (Hubbe)  else if (stringp(tmp[2])) { data= tmp[2]; } else data ="unknown function"; data+="("+
da0a822000-08-29Martin Stjernholm  desc->describe_comma_list(tmp[3..], backtrace_len)+
ba20b11999-10-15Fredrik Hübinette (Hubbe)  ")"; if(sizeof(pos)+sizeof(data) < linewidth-4) { row=sprintf("%s: %s",pos,data); }else{ row=sprintf("%s:\n%s",pos,sprintf(" %*-/s",linewidth-6,data)); }
dbe79a1999-12-07Henrik Grubbström (Grubba)  } else { row = pos;
62e87b1998-04-14Fredrik Hübinette (Hubbe)  }
ca2b071998-03-28Henrik Grubbström (Grubba)  }
a232721999-10-06Henrik Grubbström (Grubba)  else {
9798481999-12-06Henrik Grubbström (Grubba)  if (tmp) {
e0e05f2000-03-23Martin Stjernholm  if (catch (row = sprintf("%O", tmp))) row = describe_program(object_program(tmp)) + " with broken _sprintf()";
9798481999-12-06Henrik Grubbström (Grubba)  } else { row = "Destructed object"; }
a232721999-10-06Henrik Grubbström (Grubba)  } }) {
df2c632000-08-02Henrik Grubbström (Grubba)  row = sprintf("Error indexing backtrace line %d: %s (%O)!", e, err[0], err[1]);
ca2b071998-03-28Henrik Grubbström (Grubba)  }
a232721999-10-06Henrik Grubbström (Grubba)  ret += row + "\n";
ca2b071998-03-28Henrik Grubbström (Grubba)  } } return ret; }
471ed91998-04-24Fredrik Hübinette (Hubbe) 
a66ff22000-01-11Martin Stjernholm // Returns a short description of a backtrace, containing only the // error message. string describe_error (mixed trace) { if((arrayp(trace) && sizeof(trace)==2 && stringp(trace[0])) || (objectp(trace) && trace->is_generic_error)) { if (catch {
51b0fb2000-03-20Martin Stjernholm  return trace[0] || "No error message.\n";
a66ff22000-01-11Martin Stjernholm  }) { return "Error indexing backtrace!\n"; } } return sprintf ("Backtrace is of unknown type %t!\n", trace); }
471ed91998-04-24Fredrik Hübinette (Hubbe)  class Codec { mapping f=all_constants(); string nameof(mixed x) { if(mixed tmp=search(f,x)) return "efun:"+tmp;
51b0fb2000-03-20Martin Stjernholm  if (programp(x)) { if(mixed tmp=search(programs,x)) return tmp;
471ed91998-04-24Fredrik Hübinette (Hubbe) 
51b0fb2000-03-20Martin Stjernholm  if(mixed tmp=search(values(_static_modules), x)) return "_static_modules."+(indices(_static_modules)[tmp]);
471ed91998-04-24Fredrik Hübinette (Hubbe)  }
51b0fb2000-03-20Martin Stjernholm  else if (objectp(x)) if(mixed tmp=search(objects,x)) if(tmp=search(programs,tmp)) return tmp;
471ed91998-04-24Fredrik Hübinette (Hubbe)  return ([])[0]; } function functionof(string x) { if(sscanf(x,"efun:%s",x)) return f[x];
b1693a2000-04-07Fredrik Hübinette (Hubbe)  if(sscanf(x,"resolv:%s",x)) return resolv(x);
471ed91998-04-24Fredrik Hübinette (Hubbe)  return 0; } object objectof(string x) { if(sscanf(x,"efun:%s",x)) return f[x];
b1693a2000-04-07Fredrik Hübinette (Hubbe)  if(sscanf(x,"resolv:%s",x)) return resolv(x);
2f61761999-04-29Fredrik Hübinette (Hubbe)  return cast_to_object(x,0);
471ed91998-04-24Fredrik Hübinette (Hubbe)  } program programof(string x) { if(sscanf(x,"efun:%s",x)) return f[x];
b1693a2000-04-07Fredrik Hübinette (Hubbe)  if(sscanf(x,"resolv:%s",x)) return resolv(x);
2f61761999-04-29Fredrik Hübinette (Hubbe)  return cast_to_program(x,0);
471ed91998-04-24Fredrik Hübinette (Hubbe)  } mixed encode_object(object x) {
b1693a2000-04-07Fredrik Hübinette (Hubbe)  if(x->_encode) return x->_encode();
471ed91998-04-24Fredrik Hübinette (Hubbe)  error("Cannot encode objects yet.\n"); }
b1693a2000-04-07Fredrik Hübinette (Hubbe)  mixed decode_object(object o, mixed data)
471ed91998-04-24Fredrik Hübinette (Hubbe)  {
b1693a2000-04-07Fredrik Hübinette (Hubbe)  o->_decode(data);
471ed91998-04-24Fredrik Hübinette (Hubbe)  } }
a20af62000-09-26Fredrik Hübinette (Hubbe)  class Version { int major; int minor; void create(int maj, int min) { major=maj; minor=min; } #define CMP(X) (major - (X)->major) || (minor - (X)->minor) int `<(Version v) { return CMP(v) < 0; } int `>(Version v) { return CMP(v) > 0; } int `==(Version v) { return CMP(v)== 0; } int _hash() { return major * 4711 + minor ; } string _sprintf() { return sprintf("%d.%d",major,minor); } mixed cast(string type) { switch(type) { case "string": return sprintf("%d.%d",major,minor); } } } Version currentversion=Version(__MAJOR__,__MINOR__); mapping(Version:CompatResolver) compat_handler_cache=set_weak_flag( ([]), 1); CompatResolver get_compilation_handler(int major, int minor) { CompatResolver ret; Version v=Version(major,minor); if(v > currentversion) { /* do we want to make an error if major.minor > __MAJOR__.__MINOR ? */ return 0; } if(!zero_type(ret=compat_handler_cache[v])) return ret; array(Version) available=({}); #if "¤share_prefix¤"[0]!='¤' foreach(get_dir("¤share_prefix¤"), string ver) { if(sscanf(ver,"%d.%d",int maj, int min)) { Version x=Version(maj, min) ; if(x >= v) available|=({ x }); } } #endif #if "¤lib_prefix¤"[0]!='¤' foreach(get_dir("¤lib_prefix¤"), string ver) { if(sscanf(ver,"%d.%d",int maj, int min)) { Version x=Version(maj, min) ; if(x >= v) available|=({ x }); } } #endif sort(available); #ifndef RESOLVER_HACK /* We need to define RESOLVER_HACK when we add * version-specific stuff in the CompatResolver. * As long as all the compatibility is done in the * module dierctories, RESOLVER_HACK can be undefined */ /* No compat needed */ if(!sizeof(available)) { compat_handler_cache[v]=0; return 0; } /* Same as available[0] */ if(ret=compat_handler_cache[available[0]]) return compat_handler_cache[v]=ret; #endif ret=CompatResolver(v); if( v < Version(0,6)) ret->pike_module_path+=({"."}); foreach(available, Version v) { string base; #if "¤lib_prefix¤"[0]!='¤' base=combine_path("¤lib_prefix¤",sprintf("%s",v)); ret->add_module_path(combine_path(base,"modules")); ret->add_include_path(combine_path(base,"include")); #endif #if "¤share_prefix¤"[0]!='¤' base=combine_path("¤share_prefix¤",sprintf("%s",v)); ret->add_module_path(combine_path(base,"modules")); ret->add_include_path(combine_path(base,"include")); #endif } /* Add default paths */ map(pike_module_path,ret->add_module_path); map(pike_include_path,ret->add_include_path); compat_handler_cache[v] = ret; #ifndef RESOLVER_HACK compat_handler_cache[available[0]] = ret; /* may be equal to 'v' */ #endif return ret; } string _sprintf() { return "master()"; }