pike.git / lib / master.pike.in

version» Context lines:

pike.git/lib/master.pike.in:48:   // Enables the out of date warning in low_findprog().   #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;      // FIXME: PATH_SEPARATOR and UPDIR should probably be exported,   // or at least some functions that use them should be.   // cf Tools.Shoot.runpike.   // /grubba 2004-04-11 - #if defined(__NT__) || defined(__amigaos__) + #if defined(__NT__) || defined(__amigaos__) || defined(__OS2__)   #define PATH_SEPARATOR ";"   #else   #define PATH_SEPARATOR ":"   #endif      #ifdef __amigaos__   #define UPDIR "/"   #else   #define UPDIR "../"   #endif
pike.git/lib/master.pike.in:88:   // This integer variable should exist in any object that aspires to be   // the master. It gets set to 1 when the master is installed, and is   // therefore set in any object that is or has been the master. That   // makes the Encoder class encode references to the master and all   // ex-masters as references to the current master object.      // --- Functions begin here.      // Have to access some stuff without going through the resolver.   private object(_static_modules.Builtin) Builtin = _static_modules.Builtin(); - private constant Files = _static_modules.files; + private constant Files = _static_modules._Stdio;      #define Stat Files.Stat   #define capitalize(X) (upper_case((X)[..0])+(X)[1..])   #define trim_all_whites(X) (Builtin.string_trim_all_whites (X))      private function write = Files()->_stdout->write;   private function werror = Files()->_stderr->write;      // Tell Pike.count_memory this is global.   constant pike_cycle_depth = 0;
pike.git/lib/master.pike.in:124:   #define GET_MSG_DEPTH _msg_depth   #define INC_MSG_DEPTH() (++_msg_depth)   #define DEC_MSG_DEPTH() (--_msg_depth)   #endif      #endif      #ifdef RESOLV_DEBUG      #define GET_RESOLV_MSG_DEPTH GET_MSG_DEPTH - #define INC_RESOLV_MSG_DEPTH INC_MSG_DEPTH - #define DEC_RESOLV_MSG_DEPTH DEC_MSG_DEPTH + #define INC_RESOLV_MSG_DEPTH() INC_MSG_DEPTH() + #define DEC_RESOLV_MSG_DEPTH() DEC_MSG_DEPTH()      void resolv_debug (sprintf_format fmt, sprintf_args... args)   {    string pad = " " * GET_RESOLV_MSG_DEPTH;    if (sizeof (args)) fmt = sprintf (fmt, @args);    if (fmt[-1] == '\n')    fmt = pad + replace (fmt[..<1], "\n", "\n" + pad) + "\n";    else    fmt = pad + replace (fmt, "\n", "\n" + pad);    if (!werror) werror = Files()->_stderr->write;
pike.git/lib/master.pike.in:1009:   //! Check if a path @[p] is fully qualified (ie not relative).   //!   //! @returns   //! Returns 1 if the path is absolute, 0 otherwise.   int is_absolute_path(string p)   {   #ifdef __amigaos__   #define IS_ABSOLUTE_PATH(X) (search((X),":")>0)    return IS_ABSOLUTE_PATH(p);   #else - #ifdef __NT__ + #if defined(__NT__) || defined(__OS2__)    p=replace(p,"\\","/");    if(sscanf(p,"%[a-zA-Z]:%*c",string s)==2 && sizeof(s)==1)    return 1;   #define IS_ABSOLUTE_PATH is_absolute_path   #else   #define IS_ABSOLUTE_PATH(X) has_prefix((X),"/")   #endif    return has_prefix(p,"/");   #endif   }    - #ifdef __NT__ + #if defined(__NT__) || defined(__OS2__)   #define EXPLODE_PATH(X) (replace((X),"\\","/")/"/")   #else   #define EXPLODE_PATH(X) ((X)/"/")   #endif      //! @appears explode_path   //! Split a path @[p] into its components.   //!   //! This function divides a path into its components. This might seem like   //! it could be done by dividing the string on <tt>"/"</tt>, but that will
pike.git/lib/master.pike.in:1273:      #ifdef __NT__   protected void set_lc_env (mapping(string:string) env)   {    environment = ([]);    foreach (env; string var; string val)    environment[lower_case (var)] = val;   }   #endif    - //! @decl string getenv (string varname, void|int force_update) +    //! @decl mapping(string:string) getenv (void|int force_update)   //! - //! Queries the environment variables. The first variant returns the - //! value of a specific variable or zero if it doesn't exist in the - //! environment. The second variant returns the whole environment as a - //! mapping. Destructive operations on the mapping will not affect the - //! internal environment representation. + //! Queries the environment variables.   //! - //! A cached copy of the real environment is kept to make this - //! function quicker. If the optional flag @[force_update] is nonzero - //! then the real environment is queried and the cache is updated from - //! it. That can be necessary if the environment changes through other - //! means than @[putenv], typically from a C-level library. + //! @param force_update + //! A cached copy of the real environment is kept to make this + //! function quicker. If the optional flag @[force_update] is nonzero + //! then the real environment is queried and the cache is updated from + //! it. That can be necessary if the environment changes through other + //! means than @[putenv], typically from a C-level library.   //! -  + //! @returns + //! Returns the whole environment as a mapping. Destructive + //! operations on the mapping will not affect the internal + //! environment representation. + //!   //! Variable names and values cannot be wide strings nor contain   //! @expr{'\0'@} characters. Variable names also cannot contain   //! @expr{'='@} characters.   //!   //! @note   //! On NT the environment variable name is case insensitive.   //!   //! @seealso   //! @[putenv()] - string|mapping(string:string) getenv (void|int|string varname, -  void|int force_update) + mapping(string:string) getenv (void|int force_update)   { -  // Variants doesn't seem to work well yet. -  if (stringp (varname)) { -  if (!environment || force_update) { - #ifdef __NT__ -  set_lc_env (Builtin._getenv()); - #else -  environment = Builtin._getenv(); - #endif -  // Kill the compat environment if forced. -  compat_environment = compat_environment_copy = 0; -  } -  - #ifdef __NT__ -  varname = lower_case(varname); - #endif -  -  if (compat_environment) { -  array(string) res; -  if (!equal(res = compat_environment[varname], -  compat_environment_copy[varname])) { -  // Something has messed with the compat environment mapping. -  putenv(varname, res && res[1]); -  } -  } -  -  return environment[varname]; -  } -  -  else { -  force_update = varname; -  +     mapping(string:string) res;       if (force_update) {    res = Builtin._getenv();   #ifdef __NT__    set_lc_env (res);   #else    environment = res + ([]);   #endif    // Kill the compat environment if forced.    compat_environment = compat_environment_copy = 0;    }       else {    if (compat_environment &&    !equal(compat_environment, compat_environment_copy)) { -  foreach(compat_environment; varname; array(string) pair) { +  foreach(compat_environment; string varname; array(string) pair) {    if (!equal(pair, compat_environment_copy[varname])) {    putenv(pair[0], pair[1]);    }    } -  foreach(compat_environment_copy; varname; array(string) pair) { +  foreach(compat_environment_copy; string varname; array(string) pair) {    if (!compat_environment[varname]) {    putenv(pair[0]);    }    }    }   #ifdef __NT__    // Can't use the cached environment since variable names have been    // lowercased there.    res = Builtin._getenv();    if (!environment) set_lc_env (res);   #else    if (!environment) environment = Builtin._getenv();    res = environment + ([]);   #endif    }       return res;   } -  +  + //! @decl string getenv (string varname, void|int force_update) + //! + //! Query the value of a specific environment variable. + //! + //! @param varname + //! Environment variable to query. + //! + //! @param force_update + //! A cached copy of the real environment is kept to make this + //! function quicker. If the optional flag @[force_update] is nonzero + //! then the real environment is queried and the cache is updated from + //! it. That can be necessary if the environment changes through other + //! means than @[putenv], typically from a C-level library. + //! + //! @returns + //! Returns the value of the environment variable @[varname] + //! if it exists, and @expr{0@} (zero) otherwise. + //! + //! Variable names and values cannot be wide strings nor contain + //! @expr{'\0'@} characters. Variable names also cannot contain + //! @expr{'='@} characters. + //! + //! @note + //! On NT the environment variable name is case insensitive. + //! + //! @seealso + //! @[putenv()] + variant string getenv (string varname, void|int force_update) + { +  if (!environment || force_update) { + #ifdef __NT__ +  set_lc_env (Builtin._getenv()); + #else +  environment = Builtin._getenv(); + #endif +  // Kill the compat environment if forced. +  compat_environment = compat_environment_copy = 0;    }    -  + #ifdef __NT__ +  varname = lower_case(varname); + #endif +  +  if (compat_environment) { +  array(string) res; +  if (!equal(res = compat_environment[varname], +  compat_environment_copy[varname])) { +  // Something has messed with the compat environment mapping. +  putenv(varname, res[?1]); +  } +  } +  +  return environment[varname]; + } +    void putenv (string varname, void|string value)   //! Sets the environment variable @[varname] to @[value].   //!   //! If @[value] is omitted or zero, the environment variable   //! @[varname] is removed.   //!   //! @[varname] and @[value] cannot be wide strings nor contain   //! @expr{'\0'@} characters. @[varname] also cannot contain   //! @expr{'='@} characters.   //!
pike.git/lib/master.pike.in:1598:    if (array|object e = catch (bt = get_backtrace (err)))    handle_error (e);    throw (CompileCallbackError (call_describe_error (err), bt));   }      protected void call_compile_warning (object handler, string file,    string msg, mixed ... args)   {    if (sizeof (args)) msg = sprintf (msg, @args);    msg = trim_all_whites (msg); -  if (handler && handler->compile_warning) +  if (handler?->compile_warning)    handler->compile_warning (file, 0, msg);    else if (master()->compile_warning)    master()->compile_warning (file, 0, msg);    else    compile_warning (file, 0, msg);   }      #if constant(_static_modules.Builtin.mutex)   #define THREADED   _static_modules.Builtin.mutex compilation_mutex = Builtin.mutex();
pike.git/lib/master.pike.in:1838:    foreach(query_precompiled_names(fname), string oname) {    int o_mtime = get_precompiled_mtime (oname);    if (o_mtime >= 0) {    if (o_mtime >= s->mtime) {    mixed err=catch {    object|program decoded;    AUTORELOAD_CHECK_PRECOMPILED_FILE (oname);    resolv_debug ("low_findprog %s: decoding dumped\n", fname);    INC_RESOLV_MSG_DEPTH();    decoded = decode_value(read_precompiled (oname), -  (handler && handler->get_codec || +  (handler?->get_codec ||    get_codec)(fname, mkobj, handler));    DEC_RESOLV_MSG_DEPTH();    resolv_debug ("low_findprog %s: dump decode ok\n", fname); -  if (decoded && decoded->this_program_does_not_exist) { +  if (decoded?->this_program_does_not_exist) {    resolv_debug ("low_findprog %s: program claims not to exist\n",    fname);    return programs[fname] = 0;    }    else {    if (objectp(decoded)) {    resolv_debug("low_findprog %s: decoded object %O\n",    fname, decoded);    objects[ret = object_program(decoded)] = decoded;    } else {
pike.git/lib/master.pike.in:1935:    else    compile_cb_rethrow (err);    }    else    resolv_debug ("low_findprog %s: loaded binary\n", fname);   #endif /* load_module */    }       AUTORELOAD_FINISH(ret,programs,fname);    -  if (ret && ret->this_program_does_not_exist) { +  if (ret?->this_program_does_not_exist) {    resolv_debug ("low_findprog %s: program says it doesn't exist\n", fname);    return programs[fname] = 0;    }    else {    resolv_debug("low_findprog %s: returning %O\n", fname, ret);    return programs[fname]=ret;    }    }       resolv_debug ("low_findprog %s: file not found\n", fname);
pike.git/lib/master.pike.in:2084:    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);    if (programp (ret)) return ret;    error("Cast %O to program failed%s.\n",    pname,    (current_file && current_file!="-") ? sprintf(" in %O",current_file) : "");   }       + protected string narrowify_string(string s) + { +  if (Builtin.string_width(s) <= 8) return s; +  // Perform Unicode escaping. +  return map(s/"", +  lambda(string s) { +  if (Builtin.string_width(s) <= 8) return s; +  int c = s[0] & 0xffffffff; +  if (c <= 0xffff) return sprintf("\\u%04x", c); +  return sprintf("\\U%08x", c); +  }) * ""; + } +    //! This function is called when an error occurs that is not caught   //! with catch().   void handle_error(array|object trace)   {    // NB: Use predef::trace() to modify trace level here.    // predef::trace(2);    if(mixed x=catch {    werror(call_describe_backtrace(trace));    }) {    // One reason for this might be too little stack space, which    // easily can occur for "out of stack" errors. It should help to    // tune up the STACK_MARGIN values in interpret.c then.    werror("Error in handle_error in master object:\n");    if(catch {    // NB: Splited werror calls to retain some information    // even if/when werror throws.    catch {    if (catch {    string msg = [string]x[0];    array bt = [array]x[1]; -  werror("%s", msg); -  werror("%O\n", bt); +  werror("%s", narrowify_string(msg)); +  werror(narrowify_string(sprintf("%O\n", bt)));    }) { -  werror("%O\n", x); +  werror(narrowify_string(sprintf("%O\n", x)));    }    }; -  werror("Original error:\n" -  "%O\n", trace); +  werror(narrowify_string(sprintf("Original error:\n" +  "%O\n", trace)));    }) {    werror("sprintf() failed to write error.\n");    }    }    // predef::trace(0);   }      /* This array contains the names of the functions    * that a replacing master-object may want to override.    */
pike.git/lib/master.pike.in:2195:   {    foreach(master_efuns, string e)    if (!zero_type(this[e]))    add_constant(e, this[e]);    else    error("Function %O is missing from master.pike.\n", e);       add_constant("__dirnode", dirnode);    add_constant("__joinnode", joinnode);    -  add_constant("strlen", sizeof); +     add_constant("write", write);    add_constant("werror", werror);    // To make it possible to overload get_dir and file_stat later on.    // It's not possible to replace efuns with normal functions in .o-files       add_constant("get_dir", master_get_dir );    add_constant("file_stat", lambda( string f, int|void d ) { return file_stat(f,d);} );      #define CO(X) add_constant(#X,Builtin.__backend->X)    CO(call_out);
pike.git/lib/master.pike.in:2406:    int index;    foreach(paths; index; string other_fname) {    if (prio_from_filename(other_fname) <= prio) break;    }    file_paths[base] = paths[..index-1] + ({ fname }) + paths[index..];    }    }       class module_checker    { -  int `!() +  protected int `!()    {    resolv_debug ("dirnode(%O)->module_checker()->`!()\n",dirname);       if (mixed err = catch {    // Look up module.    if (module = cache["module"] || low_ind("module", 1)) {    /* This allows for `[] to have side effects first time    * it is called. (Specifically, the Calendar module uses    * this).    */
pike.git/lib/master.pike.in:2438:    // The error will then typically be:    // "Cannot call functions in unfinished objects."       // Pretend not to exist for now...    resolv_debug("dirnode(%O)->module_checker()->`!() => failure, doesn't exist\n",    dirname);    return 1;    }    }    -  mixed `[](string index) +  protected mixed `[](string index)    {    resolv_debug ("dirnode(%O)->module_checker()[%O] => %O\n", -  dirname, index, module && module[index]); -  return module && module[index]; +  dirname, index, module[?index]); +  return module[?index];    } -  array(string) _indices() { if(module) return indices(module); } -  array _values() { if(module) return values(module); } +  protected array(string) _indices() { if(module) return indices(module); } +  protected array _values() { if(module) return values(module); }    }       protected mixed low_ind(string index, int(0..1)|void set_module)    {    array(string) paths;       INC_RESOLV_MSG_DEPTH();       if (!(paths = file_paths[index])) {    DEC_RESOLV_MSG_DEPTH();
pike.git/lib/master.pike.in:2573:    resolv_debug ("dirnode(%O)->ind(%O) => not found in module\n",    dirname, index);    }    else    resolv_debug ("dirnode(%O)->ind(%O) => no module\n", dirname, index);       DEC_RESOLV_MSG_DEPTH();    return low_ind(index);    }    -  mixed `[](string index) +  protected mixed `[](string index)    {    mixed ret;   #ifdef MODULE_TRACE    werror("%*nDirnode(%O) cache[%O] ?????\n",    sizeof(backtrace()),dirname,index);   #endif    if(!zero_type(ret=cache[index]))    {   #ifdef MODULE_TRACE    werror("%*nDirnode(%O) cache[%O] => %O%s\n",
pike.git/lib/master.pike.in:2653:    dirname, module, indices(module));    map(indices(module), safe_index);    }       map(indices(file_paths), safe_index);    _cache_full = (object_program(module) != __null_program);    resolv_debug ("dirnode(%O) => Cache %s.\n", dirname,    _cache_full?"full":"partially filled");    }    -  protected array(string) _indices() +  protected protected array(string) _indices()    {    fill_cache();    // Note: Cannot index cache at all here to filter out the    // ZERO_TYPE values since that can change the order in the    // mapping, and _indices() has to return the elements in the same    // order as a nearby _values() call.    return filter (indices (cache), map (values (cache), `!=, ZERO_TYPE));    }    -  protected array(mixed) _values() +  protected protected array(mixed) _values()    {    fill_cache();    return values(cache) - ({ZERO_TYPE});    }       void delete_value (mixed val)    {    if (string name = search (cache, val)) {    m_delete (cache, name);    _cache_full = 0;
pike.git/lib/master.pike.in:2801:    name && !has_value (name, "|") &&    (name == "predef::" ? index : name + "." + index));    }       DEC_RESOLV_MSG_DEPTH();    resolv_debug ("joinnode(%O)->ind(%O) => not found. Trying fallback %O\n",    joined_modules, index, fallback_module);    return fallback_module[index];    }    -  mixed `[](string index) +  protected mixed `[](string index)    {    mixed ret;    if (!zero_type(ret = cache[index])) {    if (ret != ZERO_TYPE) {    return ret;    }    return UNDEFINED;    }    ret = ind(index);   
pike.git/lib/master.pike.in:2848:    `[](index);    }    }    }    foreach(indices(fallback_module), string index) {    `[](index);    }    _cache_full = 1;    }    -  array(string) _indices() +  protected array(string) _indices()    {    fill_cache();    // Note: Cannot index cache at all here to filter out the    // ZERO_TYPE values since that can change the order in the    // mapping, and _indices() has to return the elements in the same    // order as a nearby _values() call.    return filter (indices (cache), map (values (cache), `!=, ZERO_TYPE));    }    -  array(mixed) _values() +  protected array(mixed) _values()    {    fill_cache();    return values(cache) - ({ZERO_TYPE});    }       void delete_value (mixed val)    {    if (string name = search (cache, val))    m_delete (cache, name);    for (int i = 0; i < sizeof (joined_modules); i++) {
pike.git/lib/master.pike.in:2881:    joined_modules = joined_modules[..i - 1] + joined_modules[i + 1..];    i--;    }    else if (objectp (o) && (o->is_resolv_dirnode || o->is_resolv_joinnode))    o->delete_value (val);    else if (string name = mappingp (o) && search (o, val))    m_delete (o, name);    }    }    -  int `== (mixed other) +  protected int `== (mixed other)    {    return objectp (other) && (other->is_resolv_joinnode == 1) &&    equal (mkmultiset (joined_modules), mkmultiset (other->joined_modules));    }       array(object) _encode()    {    return joined_modules;    }   
pike.git/lib/master.pike.in:3459:    //!    string read_include(string f)    {    AUTORELOAD_CHECK_FILE(f);    if (array|object err = catch {    return master_read_file (f);    })    compile_cb_rethrow (err);    }    -  string _sprintf(int t) +  protected string _sprintf(int t)    {    return t=='O' && sprintf("CompatResolver(%O)",ver);    }   }      inherit CompatResolver;      //!   class Pike06Resolver   {
pike.git/lib/master.pike.in:3526:    mixed v = (resolver||this)->resolv(sym);    if(!v)    error("Could not resolve %s. "    "(Perhaps the installed pike tree has been moved.)\n", sym);    return v;   };      //! 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. - void _main(array(string) orig_argv) + void _main(array(string(0..255)) orig_argv)   {    array(string) argv=copy_value(orig_argv);    int debug,trace,run_tool;    object tmp;    string postparseaction=0;       predefines = initial_predefines =    Builtin._take_over_initial_predefines();    _pike_file_name = orig_argv[0];    _master_file_name = __FILE__;
pike.git/lib/master.pike.in:3737:       foreach(q, array opts)    {    switch(opts[0])    {    case "dumpversion":    write("%d.%d.%d\n", __REAL_MAJOR__, __REAL_MINOR__, __REAL_BUILD__);    exit(0);       case "version": -  exit(0, string_to_utf8(version() + " Copyright © 1994-2011 Linköping University\n" +  exit(0, string_to_utf8(version() + " Copyright © 1994-2013 Linköping University\n"    "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 COPYRIGHT in the Pike distribution for more details.\n"));       case "help":    exit( 0, main_resolv("Tools.MasterHelp")->do_help(opts[1]) );       case "features":    postparseaction="features";    break;
pike.git/lib/master.pike.in:3783:       default:    exit(1, "Unknown path type %s\n", opts[1]);    }    exit(0);    }       exit(0, format_paths());       case "execute": - #ifdef __AUTO_BIGNUM__ +     main_resolv( "Gmp.bignum" ); - #endif /* __AUTO_BIGNUM__ */ -  +     random_seed((time() ^ (getpid()<<8)));    argv = tmp->get_args(argv,1);       program prog;    mixed compile_err = catch {;    if(cur_compat_ver <= Version(7,4))    prog = compile_string(    "mixed create(int argc, array(string) argv,array(string) env){"+    opts[1]+";}");    else if (intp (opts[1]))
pike.git/lib/master.pike.in:3854:    ret = 10;    }    if(stringp(ret)) {    write(ret);    if(ret[-1]!='\n') write("\n");    }    if(!intp(ret) || ret<0) ret=0;    exit(ret);       case "preprocess": - #ifdef __AUTO_BIGNUM__ +     main_resolv( "Gmp.bignum" ); - #endif /* __AUTO_BIGNUM__ */ +     write(cpp(master_read_file(opts[1]),opts[1]));    exit(0);    }    }       argv = tmp->get_args(argv,1);    }    else    cur_compat_ver = Version (compat_major, compat_minor);   
pike.git/lib/master.pike.in:3886:    "WWW...........http://pike.lysator.liu.se/\n"    "\n"    "pike binary..."+_pike_file_name+"\n"+    format_paths() + "\n"    "Features......"+    main_resolv( "Tools.Install.features" )()*"\n "+    "\n");    exit(0);    }    - #ifdef __AUTO_BIGNUM__ +     main_resolv( "Gmp.bignum" ); - #endif /* __AUTO_BIGNUM__ */ -  +     random_seed(time() ^ (getpid()<<8));       if(sizeof(argv)==1)    {    if(run_tool) {    werror("Pike -x specificed without tool name.\n"    "Available tools:\n");    mapping t = ([]);    int i;    object ts = main_resolv("Tools.Standalone",
pike.git/lib/master.pike.in:3999:    if(cur_compat_ver <= Version(7,4)) {    script=prog();    }    else {    script=prog(argv);    }    if(!script->main)    error("Error: %s has no main().\n", argv[0]);    if (cur_compat_ver <= Version (7, 6))    ret=script->main(sizeof(argv),argv,getenv()); +  else if (cur_compat_ver <= Version (8, 0)) +  ret = script->main(sizeof(argv),argv);    else -  +  { +  mixed first_arg = __get_first_arg_type(_typeof(script->main)); +  // NB: first_arg may be zero eg in case main() ignores all args. +  if( first_arg && (typeof(argv) <= first_arg) ) { +  // argv accepted as first argument. +  ret=script->main(argv); +  } else    ret=script->main(sizeof(argv),argv); -  +  }    };    // Disable tracing.    trace = predef::trace(trace);    if (err) {    handle_error (err);    ret = 10;    }    if(!intp(ret))    exit(10, "Error: Non-integer value %O returned from main.\n", ret);   
pike.git/lib/master.pike.in:4030:    while(1)    Builtin.__backend(3600.0);    };    master()->handle_error(err);    }   }      #if constant(thread_local)   object inhibit_compile_errors = thread_local();    - void set_inhibit_compile_errors(mixed f) + //! Set the compile error, warning and exception behaviour. + //! + //! @param behaviour + //! The desired behaviour. One of: + //! @mixed + //! @type int(0..0) + //! Output compilation errors and warnings to @tt{stderr@}. + //! This is the default behaviour. + //! @type int(1..1) + //! Inhibit output of compilator diagnostics. + //! @type function(string, int, string:void) + //! Function to call for compilation errors. Compilation + //! warnings and exceptions are inhibited. + //! + //! The function will be called with the same arguments + //! as those passed to @[compile_error()]. + //! @type CompilationHandler + //! Compilation handler to use for diagnostics. + //! @endmixed + //! + //! @note + //! Note that the behaviour is thread local, and is not copied + //! to new threads when they are created. + //! + //! @seealso + //! @[get_inhibit_compile_errors()] + void set_inhibit_compile_errors(mixed behaviour)   { -  inhibit_compile_errors->set(f); +  inhibit_compile_errors->set(behaviour);   }    -  + //! Get the current compile error, warning and exception behaviour. + //! + //! See @[set_inhibit_compile_errors()] for details. + //! + //! @seealso + //! @[set_inhibit_compile_errors()]   mixed get_inhibit_compile_errors()   {    return inhibit_compile_errors->get();   }   #else /* !constant(thread_local) */   mixed inhibit_compile_errors;      void set_inhibit_compile_errors(mixed f)   {    inhibit_compile_errors=f;
pike.git/lib/master.pike.in:4088:   {    function(string:string) f=_trim_file_name_cb;    _trim_file_name_cb=s;    return f;   }         //! This function is called whenever a compile error occurs. @[line]   //! is zero for errors that aren't associated with any specific line.   //! @[err] is not newline terminated. + //! + //! @seealso + //! @[compile_warning()], @[compile_exception()], + //! @[get_inhibit_compile_errors()], @[set_inhibit_compile_errors()],   void compile_error(string file,int line,string err)   {    mixed val;    if(! (val = get_inhibit_compile_errors() ))    {    werror( "%s:%s:%s\n",trim_file_name(file), -  line?(string)line:"-",err ); +  line?(string)line:"-",narrowify_string(err) );    }    else if(objectp(val) ||    programp(val) ||    functionp(val))    {    if (objectp(val) && val->compile_error) {    val->compile_error(file, line, err);    } else if (callablep(val)) {    val(file, line, err);    }    }   }         //! This function is called whenever a compile warning occurs. @[line]   //! is zero for warnings that aren't associated with any specific   //! line. @[err] is not newline terminated. -  + //! + //! @seealso + //! @[compile_error()], @[compile_exception()], + //! @[get_inhibit_compile_errors()], @[set_inhibit_compile_errors()],   void compile_warning(string file,int line,string err)   {    mixed val;       if(!(val = get_inhibit_compile_errors() ))    {    if(want_warnings)    werror( "%s:%s: Warning: %s\n",trim_file_name(file), -  line?(string)line:"-",err ); +  line?(string)line:"-",narrowify_string(err) );    }    else if (objectp(val) && val->compile_warning) {    ([function(string,int,string:void)]([object]val)    ->compile_warning)(file, line, err);    }   }         //! This function is called when an exception is caught during   //! compilation. Its message is also reported to @[compile_error] if   //! this function returns zero. -  + //! + //! @seealso + //! @[compile_error()], @[compile_warning()], + //! @[get_inhibit_compile_errors()], @[set_inhibit_compile_errors()],   int compile_exception (array|object trace)   {    if (objectp (trace) && ([object]trace)->is_cpp_or_compilation_error)    // Errors thrown by cpp(), compile() or a compile callback should    // be reported as a normal compile error, so let the caller do    // just that.    return 0;    if (mixed val = get_inhibit_compile_errors()) {    if (objectp(val) && ([object]val)->compile_exception)    return ([function(object:int)]([object]val)
pike.git/lib/master.pike.in:4185:   }         protected object Charset;      //! This function is called by cpp() when it wants to do   //! character code conversion.   string decode_charset(string data, string charset)   {    if (!Charset) { -  object mod = [object]resolv("Locale"); -  -  Charset = [object](mod && mod["Charset"]); +  Charset = [object]resolv("Charset");    if (!Charset) -  compile_cb_error("Cannot handle charset - no Locale.Charset module found."); +  compile_cb_error("Cannot handle charset - no Charset module found.");    }       if (mixed err = catch {    object decoder = ([function(string:object)]Charset.decoder)(charset);    return ([function(void:string)]([function(string:object)]decoder->    feed)(data)->drain)();    })    compile_cb_rethrow (err);   }   
pike.git/lib/master.pike.in:4325:    default:    /* object or type. */    if (catch {    if(string tmp=sprintf("%O", m)) res = tmp;    }) {    // Extra paranoia case.    res = sprintf("Instance of %O", _typeof(m));    }    break;    } +  // Objects may have _sprintfs that output wide characters, +  // and function names may be wide, etc... +  res = narrowify_string(res);    if (stringp(ident[m]))    return ident[m] + "=" + res;    return res;    }       string describe_comma_list(array x, int maxlen)    {    string ret="";       if(!sizeof(x)) return "";
pike.git/lib/master.pike.in:5027:    return bt;   }         #ifdef ENCODE_DEBUG   # define ENC_MSG(X...) do werror (X); while (0)   # define ENC_RETURN(val) do { \    mixed _v__ = (val); \    werror (" returned %s\n", \    zero_type (_v__) ? "UNDEFINED" : \ -  sprintf ("%O", _v__)); \ +  narrowify_string(sprintf ("%O", _v__))); \    return _v__; \   } while (0)   #else   # define ENC_MSG(X...) do {} while (0)   # define ENC_RETURN(val) do return (val); while (0)   #endif      #ifdef DECODE_DEBUG   # define DEC_MSG(X...) do werror (X); while (0)   # define DEC_RETURN(val) do { \    mixed _v__ = (val); \    werror (" returned %s\n", \    zero_type (_v__) ? "UNDEFINED" : \ -  sprintf ("%O", _v__)); \ +  narrowify_string(sprintf ("%O", _v__))); \    return _v__; \   } while (0)   #else   # define DEC_MSG(X...) do {} while (0)   # define DEC_RETURN(val) do return (val); while (0)   #endif      class Encoder   //! @appears Pike.Encoder   //!
pike.git/lib/master.pike.in:5157:    return "r" + name;    }       if (objectp (resolved)) {    if (object_program (resolved) == what) {    ENC_MSG (" compare_resolved: %O is program of %O\n", what, resolved);    append = ({'p'});    break compare;    }    -  if (resolved->is_resolv_dirnode) +  if ((resolved->is_resolv_joinnode) && +  (sizeof(resolved->joined_modules) == 1)) { +  ENC_MSG(" compare_resolved: %O is a single element joinnode.\n", +  resolved); +  resolved = resolved->joined_modules[0]; +  } +  if (resolved->is_resolv_dirnode) {    if (resolved->module == what) {    ENC_MSG (" compare_resolved: %O is dirnode module of %O\n", what, resolved);    append = ({'m'});    resolved = resolved->module;    break compare;    }    else if (object_program (resolved->module) == what) {    ENC_MSG (" compare_resolved: %O is program of dirnode module of %O\n",    what, resolved);    append = ({'m', 'p'});    break compare;    }    else    ENC_MSG (" compare_resolved: %O is different from dirnode module %O\n",    what, resolved->module); -  +  }   #if 0    // This is only safe if the joinnode modules don't conflict,    // and we don't know that.    if (resolved->is_resolv_joinnode) {    ENC_MSG (" compare_resolved: searching for %O in joinnode %O\n",    what, resolved);    foreach (resolved->joined_modules, mixed part)    if (string|array name = compare_resolved (name, what, part,    module_object)) {    if (module_object) module_object[0] = resolved;    return name;    }    }   #endif -  +  } else { +  ENC_MSG(" compare_resolved: %O is not an object.\n", resolved);    }       ENC_MSG (" compare_resolved: %O is different from %O\n", what, resolved);    return 0;    }       name = "r" + name;    string|array res = name;       if (append)
pike.git/lib/master.pike.in:5384:    if (!objectp (parent)) {    object parent_obj = objects[parent];    if (objectp (parent_obj)) {    ENC_MSG (" found object for parent program in objects: %O\n", parent_obj);    parent = parent_obj;    }    }       array parent_object = ({0});    string|array parent_name = nameof (parent, parent_object); -  if (!parent_name) { +  if (!parent_name || (parent_name == "o")) {    ENC_MSG (" inside the thing to encode - encoding recursively\n");    return UNDEFINED;    }       else {    ENC_MSG(" parent has name: %O\n", parent_name);    if (objectp (parent_object[0])) parent = parent_object[0];    if (parent["_module_value"] == what &&    objects_reverse_lookup (parent)) {    ENC_MSG (" found as _module_value of parent module\n");
pike.git/lib/master.pike.in:5744:    if(maj==-1) maj = __REAL_MAJOR__;    if(min==-1) min = __REAL_MINOR__;    major = maj;    minor = min;    }      #define CMP(X) ((major - ([object]X)->major) || (minor - ([object]X)->minor))       //! Methods define so that version objects    //! can be compared and ordered. -  int `<(mixed v) { return objectp(v) && CMP(v) < 0; } -  int `>(mixed v) { return objectp(v) && CMP(v) > 0; } -  int `==(mixed v) { return objectp(v) && CMP(v)== 0; } -  int __hash() { return major * 4711 + minor ; } +  protected int `<(mixed v) { return objectp(v) && CMP(v) < 0; } +  protected int `>(mixed v) { return objectp(v) && CMP(v) > 0; } +  protected int `==(mixed v) { return objectp(v) && CMP(v)== 0; } +  protected int __hash() { return major * 4711 + minor ; }    -  string _sprintf(int t) { +  protected string _sprintf(int t) {    switch(t) {    case 's': return sprintf("%d.%d",major,minor);    case 'O': return sprintf("%O(%s)", this_program, this);    }    }       //! The version object can be casted into a string. -  mixed cast(string type) +  protected mixed cast(string type)    {    switch(type)    {    case "string":    return sprintf("%d.%d",major,minor);    }    }   }      //! Version information about the current Pike version.