pike.git / lib / master.pike.in

version» Context lines:

pike.git/lib/master.pike.in:1:   // -*- Pike -*-   //   // Master Control Program for Pike.   //   // This file is part of Pike. For copyright information see COPYRIGHT.   // Pike is distributed under GPL, LGPL and MPL. See the file COPYING   // for more information.   //      #pike __REAL_VERSION__ + //#charset iso-8859-1 // hardcoded, can not be changed   //#pragma strict_types   #pragma dynamic_dot      //! @appears predef::MasterObject   //!   //! Master control program for Pike.   //!   //! @seealso   //! @[predef::master()], @[predef::replace_master()]   
pike.git/lib/master.pike.in:87:   //! @seealso   //! @[compat_major]   int compat_minor=-1;      //! Show compilation warnings from compilation of @[cpp()]   //! @expr{#if constant()@} expressions.   //!   //! This is typically set via the option @expr{"--picky-cpp"@}.   int show_if_constant_errors = 0;    - int is_pike_master = 0; - // 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. + protected int _is_pike_master = 0;    -  + //! @decl int is_pike_master + //! 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. +  + int `is_pike_master() + { +  return _is_pike_master; + } + void `is_pike_master=(int one) + { +  _is_pike_master = one; +  if (one) { +  add_constants(); +  } + } +  +    mapping(string:object) fs_map = ([]);   object root_fs;   // --- 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._Stdio;      #define Stat Files.Stat   #define capitalize(X) (upper_case((X)[..0])+(X)[1..])
pike.git/lib/master.pike.in:339:    mixed encode_object(object x);    // Codec::Decoder:    extern string fname;    extern int mkobj;    object __register_new_program(program p);    object objectof (string|array what);    function functionof (string|array what);    program programof (string|array what);    void decode_object(object o, mixed data);    -  string _sprintf(int t); +  __deprecated__ string _sprintf(int t);       // ---       extern int show_if_constant_errors;    extern mapping(string:string) initial_predefines;    extern joinnode root_module;    extern mapping(object:joinnode) handler_root_modules;    extern array(string) system_module_path;    extern CompatResolver fallback_resolver;    joinnode get_root_module(object|void current_handler);
pike.git/lib/master.pike.in:541:   //! a path again, use @[combine_path()].   //!   array(string) explode_path(string p)   {    array(string) r = EXPLODE_PATH(p);    if(r[0] == "" && sizeof(p))    r[0] = "/";    return r;   }    - //! Returns all but the last segment of a path. Some example inputs and - //! outputs: - //! - //! @xml{<matrix> - //! <r><c><b>Expression</b></c><c><b>Value</b></c></r> - //! <r><c>dirname("/a/b")</c><c>"/a"</c></r> - //! <r><c>dirname("/a/")</c><c>"/a"</c></r> - //! <r><c>dirname("/a")</c><c>"/"</c></r> - //! <r><c>dirname("/")</c><c>"/"</c></r> - //! <r><c>dirname("")</c><c>""</c></r> - //! </matrix>@} - //! - //! @seealso - //! @[basename()], @[explode_path()] + #if !constant(dirname)   string dirname(string x)   {    if(x=="") return ""; -  array(string) tmp=x/":"; -  array(string) tmp2=tmp[-1]/"/"; -  tmp[-1]=tmp2[..<1]*"/"; -  if(sizeof(tmp2) >= 2 && tmp2[-2]=="") tmp[-1]+="/"; -  return tmp*":"; +  array(string) tmp = EXPLODE_PATH(x); +  if (x[0] == '/' && sizeof(tmp) < 3) return "/"; +  return tmp[..<1]*"/";   } -  + #else /* dirname */ + constant dirname = predef::dirname; + #endif /* !dirname */    - //! Returns the last segment of a path. - //! - //! @seealso - //! @[dirname()], @[explode_path()] + #if !constant(basename)   string basename(string x)   {    array(string) tmp=EXPLODE_PATH(x);    return tmp[-1];   #define BASENAME(X) (EXPLODE_PATH(X)[-1])   } -  + #else /* basename */ + constant basename = predef::basename; + #define BASENAME(X) basename(X) + #endif /* !basename */      #ifdef PIKE_AUTORELOAD      int autoreload_on;   int newest;      #define AUTORELOAD_BEGIN() \    int ___newest=newest; \    newest=0   
pike.git/lib/master.pike.in:620:      mapping(string:int) load_time=([]);   #else      #define AUTORELOAD_CHECK_FILE(X)   #define AUTORELOAD_BEGIN()   #define AUTORELOAD_FINISH(VAR,CACHE,FILE)      #endif // PIKE_AUTORELOAD    + //! @[predef::CompilerEnvironment] that supports handlers.   protected class CompilerEnvironment   { -  +  //!    inherit predef::CompilerEnvironment : OrigCompilerEnvironment;    -  +  //!    mixed resolv(string identifier, string filename,    object|void handler, object|void compat_handler)    {    return master()->resolv(identifier, filename,    handler, compat_handler);    }    -  +  //!    program handle_inherit(string inh, string current_file,    object|void handler, object|void compat_handler)    {    return master()->handle_inherit(inh, current_file,    handler, compat_handler);    }    -  +  //!    program handle_import(string module, string current_file,    object|void handler, object|void compat_handler)    {    return master()->handle_import(module, current_file,    handler, compat_handler);    }       object get_compilation_handler(int major, int minor)    {    return master()->get_compilation_handler(major, minor);    }    -  + #if constant(_static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__) +  //! +  class PikeCompiler +  { +  //! +  inherit ::this_program; +  +  //! +  object handler; +  object compat_handler; +  +  //! +  protected mixed apply_handler(string fun, mixed ... args) +  { +  function f; +  foreach(({ handler, compat_handler }), object o) { +  if (objectp(o) && functionp(f = predef::`->(o, fun))) { +  return f(@args); +  } +  } +  return CompilerEnvironment::`->(fun)(@args); +  } +  +  //! +  void report(SeverityLevel severity, string filename, int linenumber, +  string subsystem, string message, +  mixed ... extra_args) +  { +  foreach(({ handler, compat_handler }), object o) { +  if (!objectp(o)) continue; +  if (functionp(o->report)) { +  o->report(severity, filename, linenumber, +  subsystem, message, @extra_args); +  return; +  } +  if (severity < WARNING) continue; +  if (severity >= ERROR) { +  if (functionp(o->compile_error)) { +  o->compile_error(filename, linenumber, +  sizeof(extra_args)? +  sprintf(message, @extra_args): +  message); +  return; +  } +  } else { +  if (functionp(o->compile_warning)) { +  o->compile_warning(filename, linenumber, +  sizeof(extra_args)? +  sprintf(message, @extra_args): +  message); +  return; +  } +  } +  } +  CompilerEnvironment::report(severity, filename, linenumber, +  subsystem, message, @extra_args); +  } +  +  //! +  mixed resolv(string identifier) +  { +  return apply_handler(__func__, identifier, current_file, +  handler, compat_handler); +  } +  +  //! +  mapping(string:mixed)|object get_default_module() +  { +  /* FIXME: This function probably ought to merge the results from +  * both handlers. +  */ +  return apply_handler(__func__); +  } +  +  //! +  object get_compilation_handler(int major, int minor) +  { +  return apply_handler(__func__, major, minor); +  } +  +  //! +  program handle_inherit(string inh) +  { +  return apply_handler(__func__, inh, current_file, +  handler, compat_handler); +  } +  +  //! +  program handle_import(string module) +  { +  return apply_handler(__func__, module, current_file, +  handler, compat_handler); +  } +  +  //! +  void change_compiler_compatibility(int major, int minor) +  { +  if ((major == compat_major) && (minor == compat_minor)) { +  // Optimization: Already at this compat level. +  return; +  } +  if (((major == -1) && (minor == -1)) || +  ((major == __REAL_MAJOR__) && (minor == __REAL_MINOR__))) { +  if ((compat_major == __REAL_MAJOR__) && +  (compat_minor == __REAL_MINOR__)) { +  // Optimization again: Already at this compat level. +  return; +  } +  compat_handler = 0; +  } else { +  compat_handler = get_compilation_handler(major, minor); +  } +  +  ::change_compiler_compatibility(major, minor); +  } +  +  //! +  protected void create(string|void source, +  object|void handler, +  int|void major, int|void minor, +  program|void target, object|void placeholder) +  { +  this::handler = handler; +  ::create(source, UNDEFINED, major, minor, target, placeholder); +  } +  } + #endif /* _static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__ */ +  +  //!    int compile_exception(mixed err)    {    function(mixed:int) fun = master()->compile_exception;    return fun && fun(err);    }    -  +  //!    string format_exception(mixed err)    {    return 0;    }    -  +  //!    class CPP    { -  +  //!    inherit ::this_program;      #if constant(_static_modules.Builtin.__HAVE_CPP_NO_HANDLERS__) -  +  //!    object handler;    object compat_handler;   #endif    -  +  //!    protected mixed apply_handler(string fun, mixed ... args)    {    function f;    foreach(({ handler, compat_handler }), object o) {    if (objectp(o) && functionp(f = predef::`->(o, fun))) {    return f(@args);    }    }    return CompilerEnvironment::`->(fun)(@args);    }
pike.git/lib/master.pike.in:761:    sizeof(extra_args)?    sprintf(message, @extra_args):    message);    return;    }    }    }    ::report(severity, filename, linenumber, subsystem, message, @extra_args);    }    +  //!    object get_compilation_handler(int major, int minor)    {    return apply_handler(__func__, major, minor);    }      #if constant(_static_modules.Builtin.__HAVE_CPP_NO_HANDLERS__) -  +  //!    mapping(string:string|function|object) get_predefines()    {    return apply_handler(__func__);    }    -  +  //!    mixed resolv(string sym)    {    return apply_handler(__func__, sym, current_file,    handler, compat_handler);    }    -  +  //!    string handle_include(string header_file, string current_file,    int(0..1) is_local_ref)    {    return apply_handler(__func__, header_file, current_file,    is_local_ref);    }    -  +  //!    string read_include(string filename)    {    return apply_handler(__func__, filename);    }       string decode_charset(string data, string charset)    {    return apply_handler(__func__, data, charset);    }   #endif       string evaluate_define(string def, string|void arguments)    {    return apply_handler(__func__, def, arguments);    }    -  +  //!    void change_cpp_compatibility(int major, int minor)    {    if ((compat_major == major) && (compat_minor == minor)) {    return;    }       if (((major == __REAL_MAJOR__) && (minor == __REAL_MINOR__)) ||    (major < 0)) {    compat_handler = UNDEFINED;    } else {    compat_handler = get_compilation_handler(major, minor);    }    ::change_cpp_compatibility(major, minor);    }    -  +  //!    int compile_exception(mixed err)    {    return apply_handler(__func__, err);    }    -  +  //!    string format_exception(mixed err)    {    string ret = apply_handler(__func__, err);    if (ret) return ret;    if (compile_exception(err)) {    return "";    }    return 0;    }      #if constant(_static_modules.Builtin.__HAVE_CPP_NO_HANDLERS__) -  +  //! @decl void create(string|void current_file, @ +  //! int|string|void charset, object|void handler, @ +  //! void|int compat_major, void|int compat_minor, @ +  //! void|int picky_cpp) +  //! @decl void create(mapping(string:mixed) options) +  //! +  //! Initialize the preprocessor. +  //! +  //! @param options +  //! If the first argument is a mapping, no other arguments may follow. +  //! Instead, they have to be given as members of the mapping (if wanted). +  //! The following members are then recognized: +  //! +  //! @mapping +  //! @member string "current_file" +  //! Name of the current file. It is used for generating +  //! #line directives and for locating include files. +  //! @member int|string "charset" +  //! Charset to use when processing @expr{data@}. +  //! @member object "handler" +  //! Compilation handler. +  //! @member int "compat_major" +  //! Sets the major pike version used for compat handling. +  //! @member int "compat_minor" +  //! Sets the minor pike version used for compat handling. +  //! @member int "picky_cpp" +  //! Generate more warnings. +  //! @member int "keep_comments" +  //! This option keeps @[cpp()] from removing comments. +  //! Useful in combination with the prefix feature below. +  //! @member string "prefix" +  //! If a prefix is given, only prefixed directives will be +  //! processed. For example, if the prefix is @expr{"foo"@}, then +  //! @expr{#foo_ifdef COND@} and @expr{foo___LINE__@} would be +  //! processed, @expr{#ifdef COND@} and @expr{__LINE__@} +  //! would not. +  //! @endmapping +  //! +  //! @param current_file +  //! If the @[current_file] argument has not been specified, +  //! it will default to @expr{"-"@}. +  //! +  //! @param charset +  //! Turn on automatic character set detection if @expr{1@}, otherwise +  //! specifies the character set used by the input. +  //! Defaults to @expr{"ISO-10646"@}. +  //! +  //! @seealso +  //! @[compile()]       protected void create(mapping(string:mixed) options)    {    // werror("CPP(%O)\n", options);    handler = options->handler;    compat_handler = UNDEFINED;    ::create(options);    }       protected variant void create(string|void current_file,
pike.git/lib/master.pike.in:859:    CPP_OPT(charset);    CPP_OPT(handler);    CPP_OPT(compat_major);    CPP_OPT(compat_minor);    CPP_OPT(picky_cpp);   #undef CPP_OPT    local::create(options);    }   #endif    } +  + #if constant(_static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__) +  //! +  program compile(string source, object|void handler, +  int|void major, int|void minor, +  program|void target, object|void placeholder) +  { +  return PikeCompiler(source, handler, major, minor, target, placeholder)-> +  compile();    } -  + #endif /* _static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__ */ + }      protected CompilerEnvironment DefaultCompilerEnvironment =    CompilerEnvironment();    -  + #if constant(_static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__) + //! + protected program compile(string source, object|void handler, +  int|void major, int|void minor, +  program|void target, object|void placeholder) + { +  return DefaultCompilerEnvironment->compile(source, handler, +  major, minor, +  target, placeholder); + } + #endif /* _static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__ */ +  + //! @decl CompilationHandler get_active_compilation_handler() + //! + //! Returns the currently active compilation compatibility handler, or + //! @tt{0@} (zero) if none is active. + //! + //! @note + //! This function should only be used during a call of @[compile()]. + //! + //! @seealso + //! @[get_active_error_handler()], @[compile()], + //! @[master()->get_compilation_handler()], @[CompilationHandler] + protected object get_active_compilation_handler() + { +  CompilerEnvironment.PikeCompiler c = get_active_compiler(); +  return c && c->compat_handler; + } +  + //! @decl CompilationHandler get_active_error_handler() + //! + //! Returns the currently active compilation error handler + //! (second argument to @[compile()]), or @tt{0@} (zero) if none + //! is active. + //! + //! @note + //! This function should only be used during a call of @[compile()]. + //! + //! @seealso + //! @[get_active_compilation_handler()], @[compile()], @[CompilationHandler] + protected object get_active_error_handler() + { +  CompilerEnvironment.PikeCompiler c = get_active_compiler(); +  return c && c->handler; + } +  + //!   protected string cpp(string data, mapping|string|void current_file,    int|string|void charset, object|void handler,    void|int compat_major, void|int compat_minor,    void|int picky_cpp)   {    CompilerEnvironment.CPP cpp_obj =    DefaultCompilerEnvironment->CPP(current_file, charset,    handler || UNDEFINED,    compat_major, compat_minor,    picky_cpp);
pike.git/lib/master.pike.in:1157:   //!   //! @note   //! On NT the environment variable name is case insensitive.   //!   //! @seealso   //! @[putenv()]   mapping(string:string) getenv (void|int force_update)   {    mapping(string:string) res;    -  if (force_update) { +  if (force_update > 0) {    res = Builtin._getenv();   #ifdef __NT__    set_lc_env (res);   #else    environment = res + ([]);   #endif    }    else {   #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 -  +  if (force_update < 0) return environment;    }       return res;   }      //! @decl string getenv (string varname, void|int force_update)   //!   //! Query the value of a specific environment variable.   //!   //! @param varname
pike.git/lib/master.pike.in:2031:   #endif    }    return UNDEFINED;   }      /* This array contains the names of the functions    * that a replacing master-object may want to override.    */   constant master_efuns = ({    "error", + #if !constant(basename)    "basename", -  + #endif + #if !constant(dirname)    "dirname", -  + #endif    "is_absolute_path",    "explode_path",       "compile_string",    "compile_file",    "add_include_path",    "remove_include_path",    "add_module_path",    "remove_module_path",    "add_program_path",
pike.git/lib/master.pike.in:2110:   //! from the default @[RandomSystem].   //!   //! @seealso   //! @[RandomSystem()->random_string()], @[random()]      //! @decl int cp(string from, string to)   //!   //! Copies the file @[from] to the new position @[to]. This is an   //! alias for @[Stdio.cp].    - /* Note that create is called before add_precompiled_program + /* Note that add_constants() and create() are called +  * before add_precompiled_program().    */ - protected void create() + protected void add_constants()   { -  + #if constant(_static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__) +  add_constant("compile", compile); + #endif /* _static_modules.Builtin.__HAVE_COMPILER_NO_HANDLERS__ */ +  add_constant("get_active_compilation_handler", get_active_compilation_handler); +  add_constant("get_active_error_handler", get_active_error_handler);    add_constant("CompilerEnvironment", CompilerEnvironment);    add_constant("DefaultCompilerEnvironment", DefaultCompilerEnvironment);    add_constant("cpp", cpp);       foreach(master_efuns, string e)    if (has_index(this, e))    add_constant(e, this[e]);    else    error("Function %O is missing from master.pike.\n", e);   
pike.git/lib/master.pike.in:2136:   // than the enum type (aka int(1..1))   //   // doing the add_constant on the typeof directly gives int(1..1)   // instead, since the same "optimization" of the type is done in that   // case.    add_constant("bool", typeof([int(0..1)](mixed)0));       add_constant("__dirnode", dirnode);    add_constant("__joinnode", joinnode);    +  werror = locale_werror;    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", high_master_get_dir );    add_constant("file_stat", lambda( string f, int|void d ) { return file_stat(f,d);} );       object rnd = Builtin.RandomSystem();    add_constant("random", rnd->random);    add_constant("random_string", rnd->random_string);      #define CO(X) add_constant(#X,Builtin.__backend->X)    CO(call_out);    CO(_do_call_outs);    CO(find_call_out);    CO(remove_call_out);    CO(call_out_info); -  + }    -  + protected void create() + { +  add_constants(); +    #if "#share_prefix#"[0]!='#'    // add path for architecture-independant 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");
pike.git/lib/master.pike.in:2927:    if (module_node_cache[current_handler]) {    if (module_node_cache[current_handler][path]) {    return module_node_cache[current_handler][path];    }    } else {    module_node_cache[current_handler] = ([]);    }    module_node node = module_node_cache[current_handler][path] =    module_node("import::"+path, 0, current_handler);   #endif /* 0 */ -  joinnode node = joinnode(({}), current_handler); +  auto path_stat = file_stat(path); +  if (!path_stat) +  compile_cb_error("Failed to stat file: %O\n", path); +  joinnode node; +  if (path_stat->isreg) { +  node = low_cast_to_object(path, current_file, current_handler); +  } +  else if (path_stat->isdir) { +  node = joinnode(({}), current_handler);   #ifdef PIKE_MODULE_RELOC    // If we have PIKE_MODULE_RELOC enabled,    // we might need to map to multiple directories.    if(path == "/${PIKE_MODULE_PATH}" ||    has_prefix(path, "/${PIKE_MODULE_PATH}/")) {    string tmp = path[21..];    foreach(pike_module_path, string prefix) {    node->add_path(sizeof(tmp)? combine_path(prefix, tmp) : prefix);    }    } else   #endif /* PIKE_MODULE_RELOC */    node->add_path(path); -  +  }    return node;   }      program|object findmodule(string fullname, object|void handler,    void|string name)   {    program|object o;       resolv_debug ("findmodule(%O)\n", fullname);    if(!undefinedp(o=fc[fullname]) && o != no_value)
pike.git/lib/master.pike.in:3589:   //! @endnamespace      //! 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;   string _master_file_name;      // Gets set to 1 if we're in async-mode (script->main() returned <0)   private int(0..1) _async=0;    - //! Returns 1 if we´re in async-mode, e.g. if the main method has + //! Returns 1 if we're in async-mode, e.g. if the main method has   //! returned a negative number.   int(0..1) asyncp() {    return _async;   }      #if constant(thread_create)   // this must be done in __init if someone inherits the master   protected object _backend_thread=this_thread();      //! The backend_thread() function is useful to determine if you are
pike.git/lib/master.pike.in:3811:       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-2018 Linköping University\n" +  exit(0, version() + " Copyright © 1994-2018 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")); +  "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;       case "info":    postparseaction="info";
pike.git/lib/master.pike.in:4321:    return ([function(void:string)]([function(string:object)]decoder->    feed)(data)->drain)();    })    compile_cb_rethrow (err);   }         //! Class used by @[describe_backtrace()] to describe values in backtraces.   class Describer   { +  /* Attempt to avoid keeping this object around, as it may contain +  * indirect references to stuff (like mutex keys) in backtraces, +  * via the ident mapping below. +  */ +  inherit _static_modules.Builtin.DestructImmediate; +     int clipped=0;    int canclip=0;    mapping(mixed:int|string) ident = ([]);    int identcount = 0;       void identify_parts (mixed stuff)    {    // Use an array as stack here instead of recursing directly; we    // might be pressed for stack space if the backtrace being    // described is a stack overflow.
pike.git/lib/master.pike.in:4442:    case "function":    if (string tmp=describe_function([function]m)) res = tmp;    break;    case "program":    if(string tmp=describe_program([program]m)) res = tmp;    break;    default:    /* object or type. */    if (catch {    if(string tmp=sprintf("%O", m)) res = tmp; +  if (sizeof(res) > maxlen) error("Too long.\n");    }) {    // Extra paranoia case. -  res = sprintf("Instance of %O", _typeof(m)); +  if (objectp(m)) { +  res = sprintf("%O(...)", object_program(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;    }   
pike.git/lib/master.pike.in:4467:    {    string ret="";       if(!sizeof(x)) return "";    if(maxlen<0) return ",,,"+sizeof(x);       int clip=min(maxlen/2,sizeof(x));    int len=maxlen;    int done=0;    +  mapping(mixed:int|string) saved_ident = ident + ([]); +     while(1)    { -  +  int saved_clipped = clipped; +  int saved_canclip = canclip; +     array(string) z=allocate(clip);    array(int) isclipped=allocate(clip);    array(int) clippable=allocate(clip);    for(int e=0;e<clip;e++)    {    clipped=0;    canclip=0;    z[e]=describe(x[e],len);    isclipped[e]=clipped;    clippable[e]=canclip;    }    -  +  clipped = saved_clipped; +  canclip = saved_canclip; +     while(1)    {    string ret = z[..clip-1]*",";    if(done || sizeof(ret)<=maxlen+1)    {    int tmp=sizeof(x)-clip-1;    clipped=`+(0,@isclipped);    if(tmp>=0)    {    clipped++;    ret+=",,,"+tmp; -  +  +  // Ensure that we don't lose any relevant ident assignments +  // due to the clipping. +  // +  // Note that this means that we may get duplicate assignments +  // for the same value and/or unused ident numbers, but this +  // is better than getting getting references to ident numbers +  // without any assignent. Cf [PIKE-141]. +  ident = saved_ident;    }    canclip++;    return ret;    }       int last_newlen=len;    int newlen;    int clipsuggest;    while(1)    {
pike.git/lib/master.pike.in:6033:    ret = compat_handler;    }    }       // Note: May duplicate the assignment above.    compat_handler_cache[v] = ret;       return ret;   }    - string _sprintf(int t) + protected string _sprintf(int t)   {    switch(t) {    // FIXME: What good is this lying for 't'? The master is still an    // object.. /mast    case 't': return "master";    case 'O': return "master()";    }   }      //! Return a master object compatible with the specified version of Pike.
pike.git/lib/master.pike.in:6057:   //!   //! @seealso   //! @[get_compilation_handler()], @[master()]   object get_compat_master(int major, int minor)   {    if ((major < 8) || ((major == 8) && (minor < 1)))    return Pike_8_0_master::get_compat_master(major, minor);    // 8.1 and later.    return this;   } +  + private function locale_werror_cache; + protected void locale_werror(mixed ... args) + { +  function werror = locale_werror_cache; +  if (!werror) { +  catch { +  object stderr = main_resolv( "Stdio.FILE" )( "stderr", "w" ); +  stderr->set_charset( 0 ); +  werror = stderr->write; +  if (werror && !locale_werror_cache) +  locale_werror_cache = werror; +  }; +  if (!werror) +  werror = Files()->_stderr->write; +  } +  werror(@args); + }