Branch: Tag:

2002-12-05

2002-12-05 21:14:51 by Martin Nilsson <mani@lysator.liu.se>

Reset

Rev: CHANGES:1.52

1: - Changes since Pike 7.2: + Changes since Pike 7.4:   ----------------------------------------------------------------------      New/improved functionality:   ---------------------------    - o New Hilfe -  The interactive pike environment you get when running pike without -  giving a program name, has been thoroughly rewritten. Most notably -  it now supports more of the common pike constructs, and is more -  extendable and configurable. Start it and type help for more info. + o rsif +  rsif can now work recursively in a file structure if given the +  flag -r or --recursive. Example: +  pike -x rsif -r 7.4 7.6    - o AutoDoc -  The major parts of Pike now has some sort of documentation on -  class and function level thanks to the AutoDoc system which has -  been deployed during the last year. Manual dumps are published on -  http://pike.ida.liu.se/docs/reference/. +     - o pike -x -  When starting pike with the -x parameter, the pike process will -  run the named script in Tools.Standalone, giving the rest of the -  arguments as command-line switches. This is a convenient way of -  running rsif (replace string in file) and pv (the image viewer -  you may be familiar with from Tools.PV). -  - o pike -e scope -  When running command line one liners with pike -e you can now -  access the numer of arguments, the actual arguments and the -  environment variables through the variables argc, argv and env. -  - o unbug -  Embryo of a Pike debugger. Not stable nor finished. -  - o Unicode 3.2.0 -  All charts have been updated to Unicode 3.2.0. This applies both to -  the Unicode module as well as to Pike-global functionality such as -  upper_case/lower_case. unicode_to_string() also has support for -  surrogate and byteorder mark handling. -  - o Extended random() -  random() now works on floats, arrays, multisets, mappings and -  objects in addition to integers. -  - o delay()/sleep() -  sleep() no longer busywaits, which it previously did for small -  values. The old behavior is available from the delay() function. -  (This has change been made in later 7.2 releases too.) -  - o search(string, int) / has_value(string, int) -  Both of these methods now handle both looking for strings and -  integers (the unicode number for a single character). -  Examples: search("hi, ho!", '!'), has_value("Nope.", ' ') -  - o Expanded Charset module -  The character set module now has support for the character sets -  Shift_JS, UTF-7.5, EUC, Big5, CP950, UTF-16, UTF-16BE, UTF-16LE. -  It is now also easier to get the right charset codec since the -  names are normalized internally. -  - o sprintf("%O", foo) is more descriptive -  If foo is a program or an object then Pike will try to find the -  resolved name instead of returning just "program" or "object". -  However, if an object contains an _sprintf function it will still -  be called in this case. -  - o basetype(foo) -  Returns a string with the basic type of foo as opposed to -  _typeof(foo) that returns the actual type. Also available as -  sprintf("%t", foo). -  - o getenv()/putenv() -  The environment variable functions getenv and putenv is now is now -  both case insensitive on Microsoft Windows systems. This should -  make your programs more portable. -  - o Return value from catch blocks. -  The return value from catch blocks that exit normally has been -  changed from a normal zero (i.e. zero_type 0) to UNDEFINED (i.e. -  zero_type 1). -  - o SSL -  The Pike SSL implementation now supports TLS 1.0. Also the LDAP -  protocol and the HTTP.Query methods supports secure transport over -  SSL/TLS. -  -  +    Language additions:   -------------------    - o foreach(X; Y; Z) -  The foreach statement has been extended to allow iterations over -  mappings, multisets and any object that implements the iterator -  interface (see below). To make it possible to use this -  conveniently, a new syntax has been added to get both the index -  and the value in each iteration: +     -  foreach (something; index-expr; value-expr) ... -  -  This iterates over something, assigning in turn each index to -  index-expr and each value to value-expr. The index and value -  expressions can be declarations or lvalues, and they can also be -  left out if the index and/or value part isn't interesting. -  -  Note that it depends on the data type whether the iteration order -  is well defined or not; arrays and multisets are iterated over -  starting with the first element while mappings are visited in some -  arbitrary order (each element is still visited only once, though). -  - o Iterators -  As noted above, an iterator interface has been added that is now -  used in various places to iterate over different data structures. -  Not only the built-in data types are supported, but actually any -  object that fulfills the interface for iterators: -  -  When iterating over an object o, o->_get_iterator() is called to -  get an iterator object. An iterator object should at least have -  two functions, index() and value(), to get the index and value -  at the current position, a function `+=(int steps) to advance the -  current position the specified number of steps, and a `!() that -  returns zero if the end of the data set hasn't been reached yet. -  -  Also, if the object o lacks a _get_iterator function, it's assumed -  to be an iterator itself. This makes it possible to pass an -  iterator explicitly to e.g. the foreach statement. -  -  The built-in data types also have iterator classes with this -  interface. They are found as Array.Iterator, Mapping.Iterator, etc -  and can be used to iterate over these data types in some custom -  fashion. This is especially useful for mappings and multisets, -  which cannot be iterated over directly in any other way. For -  example, to get some arbitrary index in a mapping m: -  -  mixed any_index = Mapping.Iterator(m)->index(); -  - o Automap -  To perform per-element operations on arrays, there is now a convenience -  syntax for map(), that can make code more readable in some situations. -  Summing up two arrays element by element using automap looks like this: -  -  a[*] + b[*]; // the result has as many elements as the shortest array. -  -  Multiplying all elements in a by a constant: -  -  a[*] * 4711; -  -  Make an array of what sprintf("%O", a[n]) returns for all elements in a: -  -  sprintf("%O", a[*]); -  - o Implicit lambda -  A convenient way to embed code that needs pre- and/or post- -  initialization. If a statement starts with a function call -  followed directly by a brace block, then the block is transformed -  to a lambda function which is passed as the last argument to the -  function being called. -  -  The following example embeds OpenGL calls that modifies the matrix -  in an implicit lambda that will save the matrix before execution -  and restore it afterwards: -  -  void PushPop( function f ) -  { -  glPushMatrix(); -  mixed err = catch(f()); -  glPopMatrix(); -  if (err) throw(err); -  } -  -  void do_something() -  { -  PushPop() { -  glTranslate( (1.0-0.08)/2, 0.0, 0.0 ); -  draw_stuff(); -  }; -  } -  -  Note that although useful, this feature has important -  disadvantages and will probably be obsoleted by a better -  alternative in the future. The problem is that the inner brace -  block become a completely separate function instead of remaining a -  block. The difference (apart from being slower) is shown by this -  example: -  -  void do_something() -  { -  PushPop() { -  if (glError()) return; -  glTranslate( (1.0-0.08)/2, 0.0, 0.0 ); -  draw_stuff(); -  }; -  draw_more_stuff(); -  } -  -  Since the inner block is a separate function, the return statement -  doesn't exit do_something() as one might expect, causing -  draw_more_stuff() to be called even when there's a GL error. -  Another effect is that break and continue can't be associated with -  statements outside the implicit lambda block. -  -  Another method that overcomes these problems will likely be -  implemented. The problem is that it can give compatibility -  problems to change old code that uses implicit lambdas to that -  one, since e.g. return will work differently without giving any -  sort of error. -  - o Access to hidden variables in surrounding scopes -  Include the names of the surrounding classes themselves in the lookup for -  Foo::, to make it possible to address hidden variables in the scopes of -  surrounding classes, e.g: -  -  class Foo { -  int i; -  void create (int i) {Foo::i = i;} -  } -  - o global:: -  Added new keyword global to be able to access identifiers on the -  top level of the compilation unit using global::foo. -  - o global. -  All top level modules (and other identifiers in that scope) can now -  be accessed with a "global." prefix. This is useful in cases where -  local identifiers overshadow the top level, for instance in the Image -  module, where the Image.Image class would occasionally block your view. -  - o this -  Added a magic identifier "this" that can be used instead of -  this_object(). Like this_program, it only exists when there's no -  other identifier with that name. The primary reason for adding -  this magic identifier is to make it possible to address the object -  of a surrounding class with Foo::this. -  - o The program type can be specialized -  It's possible to specialize a program variable by adding a program -  identifier, much like an object variable can be specialized. E.g: -  -  program(Stdio.File) fd_prog = Stdio.File; -  - o ::_indices(), ::_values(). -  There are now two "magic" functions ::_indices() and ::_values() -  that can be used by an object to list all identifiers and their -  values in itself. They are primarily intended when the _indices() -  and _values() lfuns have been defined, to get the default -  implementations. This is to complement the "magic" ::`->() and -  ::`->=() functions that exist in earlier releases. -  - o UNDEFINED -  To generate a 0 (zero) with a zero_type(var) == 1, you previously -  had to use constructs like ([])[0]. This is now available as the -  globally available symbol UNDEFINED. -  - o _m_delete -  A class can now define a function mixed _m_delete(mixed index) to -  make the objects work like mappings with m_delete(). (This feature -  has been added to later 7.2 releases too.) -  - o Constant objects -  An object can now be constant, allowing for better -  performace and better dumping. For example used for Gmp.Bignum, -  Math.Matrix and Image.Color. -  -  +    New modules / classes / methods added:   --------------------------------------    - o ADT.History -  ADT implementation of a "leaking stack". Hilfe example: -  > object h=ADT.History(3); -  > for(int i=17; i<22; i++) h->push(i); -  Ok. -  > h->get_first_entry_num(); -  (1) Result: 3 -  > h[3]; -  (2) Result: 19 +     - o ADT.Relation.Binary -  Handles binary relations. Hilfe example: -  > object r=ADT.Relation.Binary("test"); -  > r->add(1,2)->add(2,3)->add(3,5)->add(1,4)->add(4,5); -  (1) Result: ADT.Relation.Binary("test") -  > r->find_shortest_path(1,5); -  (2) Result: ({ /* 3 elements */ -  1, -  4, -  5 -  }) -  > r->remove(1,4); -  (3) Result: ADT.Relation.Binary("test") -  > r->add(5,1); -  (4) Result: ADT.Relation.Binary("test") -  > r->find_shortest_path(1,5); -  (5) Result: ({ /* 4 elements */ -  1, -  2, -  3, -  5 -  }) -  - Array.common_prefix - Array.count - Array.greedy_diff - Array.oid_sort_func - Array.arrayify - Array.uniq2 - Array.sum -  - o Audio.Codec and Audio.Format -  Contain decoders/encoders and format parsers for audio. -  Currently WAV and MP3. -  Note: The API remains marked "unstable". -  - o Crypto.md4 -  Hash used for NT Lanmanager passwords. -  - o Crypto.crypt_md5 -  Convenience function to produce crypted $1$ style crypted -  passwords (commonly called MD5 passwords). -  - o Debug -  Many top level debug functions has moved into the Debug module to -  keep amount of top level functions less intimidating for new users -  and to make the debug functions easier to find. -  - o Debug.Tracer -  A class that when instatiated will turn on trace, and when it's -  destroyed will turn it off again. -  - o Debug.Subject -  This is a probe subject which you can send in somewhere to get -  probed (not to be confused with a probe object, which does some -  active probing). All calls to LFUNs will be printed to stderr. -  - o DVB -  Access to DVB (digital sat) resources. Controls tuner, MP2 -  audio and video decoders. Allows extract multiple channels -  at once. -  Note: Only old 0.9.4 DVB API is supported. -  - o Gmp.mpq and Gmp.mpf -  Support for GMP multi precision fractions and multi precision -  floats. Hilfe example: -  > Gmp.mpq(5,3); -  (1) Result: 5/3 -  > _->invert(); -  (2) Result: 3/5 -  > (float)_; -  (3) Result: 0.600000 -  > Gmp.mpq(5,3)+Gmp.mpq(1,2); -  (4) Result: 13/6 -  - o Gz.File -  Pike can now compress and decompress the Gzip format. This is -  still a bit experimental but the basic functions should work -  just fine. -  - o HTTP.Server -  A simple HTTP Server. -  - o Image.filled_circle(_layer) -  Returns an Image/Layer object with a filled circle on it. -  - o Image.Dims -  Can extract the dimensions of an image with a minimal amount of -  data loading. Currently handles JPEG, GIF and PNG images. Hilfe -  example: -  > Image.Dims.get(Stdio.File("test.gif")); -  (1) Result: ({ /* 2 elements */ -  1412, -  1120 -  }) -  - o Image.DWG -  Decodes the thumbnail images embedded in AutoCAD drawings. -  - o Image.Fonts -  High level API for font handling. Should be used instead of -  accessing the FreeType, TTF and Image.Font modules directly. -  - o Image.Image -  Added two new methods, blur() and grey_blur(), which are hard -  coded, MMX optimized versions of these common matrix operations. -  - o Image.JPEG -  Support for lossless transforms, such as rotating and rescaling -  the image, and handling of metadata. -  - o Image.PVR -  VQ compression/decompression added. -  - o Image.SVG -  Support for Structured Vector Graphics through the Gnome SVG -  library. Requires Gnome 2. -  - o Local -  All Pike modules and classes found in the directory hierarchies -  /usr/local/pike_modules, /opt/pike_modules, /opt/share/pike_modules, -  /usr/local/share/pike_modules, $HOME/pike_modules, and -  $PIKE_LOCAL_PATH (a :-separated list of directories) are available -  with the prefix "Local.". Local.add_path() and Local.remove_path() -  respectively adds and removes entries from the list of paths to -  inspect when resolving Local.* symbols. -  - o Locale.Language -  Support for time formatting, counting and more for various -  languages. Currently added languages are Catalan, Croatian, Czech, -  Dutch, English, Finnish, French, German, Hungarian, Italian, -  Japanese, Maori, Norwegian, Polish, Portuguese, Russian, Serbian, -  Slovenian, Spanish and Swedish. -  - o Math.Matrix -  Methods sum(), max(), min(), convolve() and dot_product() added. -  - o Math.Transforms -  Glue for supporting FFT and iFFT via libfftw and librfftw. -  - o Math -  Added the IEEE float constants inf and nan. -  - o MIME.Message -  Guess mode added. *FIXME: expand on this jhs* -  - o Oracle -  The Oracle database glue now supports CLOBs and BLOBs. -  - o Parser.Python -  Splits Python source code into text tokens. -  - o Parser.RCS -  Extracts data from RCS or CVS repositories. -  - o Parser.XML.NSTree -  This is an extended version of Parser.XML.Tree that can handle -  namespaces according to the W3C namespace specification. -  - o Protocols.X.KeySyms -  - o SDL -  Wrapper for a subset of Simple DirectMedia Layer -  functionality. Useful for writing games, movie players and other -  graphically intensive applications. -  - o Shuffler -  - o Standards.CIFF -  Experimental module to read Canon Camera Image File Format data. -  - o Standards.EXIF -  Support for the EXchangeable Image file Format for digital still -  cameras version 2.2. Support for maker notes for cameras from -  Nikon, Canon, Fuji Film, Olympus, Sanyo and Casio. -  - o Standards.FIPS10_4 -  The Federal Information Processing Standard for Countries, -  Dependencies, Areas of Special Sovereignty, and their Principal -  Administrative Divisions = american standard for countries and -  country division codes. -  - o Standards.ID3 -  ID3 tags decoder/encoder. Supports versions: 1.0, 1.1, -  2.2-2.4. Frequently used in MP3 files for encapsulating metadata. -  - o Standards.ISO639_2 -  This module has been updated with the map_to_639_1 method to -  convert from ISO 639-2/T to ISO 639-1. With the new methods -  convert_b_to_t and convert_t_to_b it is possible to convert -  between ISO 639-2/T and ISO 639-2/B. -  - o Standards.RDF -  Represents an RDF domain and allows you to perform searches in its -  relations. Currently only serializes/deserializes to N-triple -  format. -  - o Stdio -  Moved get_all_active_fd() from spider to Stdio. -  Added methods to Stdio.File: sync(), line_iterator() -  - Stdio.connect_unix - Stdio.simplify_path - Stdio.file_equal - Stdio.FILE.set_charset -  - o Stdio.expand_symlinks(string path) -  Expands all symlinks along a path (returns 0 for broken links). -  (Only available on systems with readlink.) -  - o Stdio.FakeFile -  Wraps a string and exports a Stdio.File interface. -  - o Stdio.File->grantpt() -  can now allocate a VTY on systems with /dev/ptmx support. -  -  Minimal example: -  fd = Stdio.File("/dev/ptmx", "rw" ); -  Stdio.File fd2 = Stdio.File( fd->grantpt(), "rw" ); -  Process.create_process( ({ "/bin/bash" }), ([ -  "stdin":fd2, "stdout":fd2, "stderr":fd2, "setsid":fd2, -  ]) ); -  - o String.SplitIterator -  FIXME: grubba -  - o String.Replace, String.SingleReplace -  FIXME -  - o System.Time -  Used to get the current time with sub second precision. -  - o System.Timer -  Measures the time between two calls. -  - o System.Memory -  Handles read/write from mmap'ed or allocated memory. -  - System.normalize_path - System.gettimeofday - System.get_netinfo_property (Max OS X) - System.usleep/nanosleep -  FIXME: per? -  - o Tools.PV -  Convenience tool that sets up a canvas with GTK, presents a -  picture on it and delivers a number of image inspection and -  manipulation options. This is a great tool for image work in -  Hilfe. -  -  > object i=Image.Image(32,32)->random(); -  > Tools.PV(i); -  -  The Pike Viewer tool is also accessible via "pike -x pv". -  -  +    Optimizations:   --------------    - o Machine code generation -  On systems with IA32, SPARC or PPC32 processors Pike will generate -  native machine code as byte code. This byte code can then by -  executed directly outside the virtual machine and gives a 30% -  performance boost compared to other systems. +     - o Computed goto -  - o Better module dumping -  - o Overall speed improvements. -  Function calls (new opcodes) -  sprintf -  arrays -  replace -  - o Deferred backtraces -  Most of the information in backtraces are now calculated upon -  presenting the backtrace information and not when the backtrace is -  generated. This improves the performance of catched errors. -  - o Saved 8 bytes per object for objects not using their parent scope -  -  +    Compatibility changes:   ----------------------    - The following changes are known to break compatibility. The old - behavior is emulated in the compatibility layer that is activated by - adding the preprocessor directive "#pike 7.2" to your program or by - giving the argument "-V7.2" to the pike executable. +     - o "global" has become a reserved keyword. -  - o Changed lookup rule for ::. -  Previously the identifier in front of :: was only looked up among -  the preceding inherits. Now the lookup additionally includes the -  names of the surrounding classes. The inherits inside a class -  still take precedence over the name of the class, though. -  - o Using local:: on variables is an error. -  Previously the construct local::foo could be used to access the -  identifier "foo" in the class scope if it had been overridden by -  an argument or function variable. That is however only a -  side-effect of the real use for local::, namely to bind the -  identifier statically at that point only, to avoid getting an -  overridden version. In the case of variables this leads to -  questionable semantics, which is the reason it's been made an -  error in this version. Pike 7.2 didn't implement it correctly; -  there local:: on variables had only the effect to access the class -  scope. Now a proper way to access hidden identifiers has been -  added, so all such uses of local:: should be replaced with -  this_program::. -  - o Identifier lookup -  The search algorithm for finding identifiers from inherited classes -  has been changed to look for the most recent definition in the most -  recent inherit. In Pike 7.2 and prior, it looked up the last -  definition regardless of inherit depth, unless there was a -  definition in the current program. (This actually changed more than -  once during 7.3 - between 7.3.23 and 7.3.32, it looked up the most -  recent definition with the least inherit depth.) This example shows -  what the lookup strategies would find: -  -  class A { -  int foo() {} -  } -  -  class B { -  int foo() {} -  inherit A; -  } -  -  class C { -  inherit B; -  } -  -  class D { -  inherit B; -  inherit C; -  } -  -  Lookup of identifier "foo" in D(): -  -  D-+-B-+-foo (Pike 7.3.23 --- Pike 7.3.32) -  | | -  | +-A---foo -  | -  +-C---B-+-foo Pike 7.3.33 --- (present day) -  | -  +-A---foo --- Pike 7.3.22 -  -  Lookup of identifier "foo" in C(): -  -  C---B-+-foo Pike 7.3.23 --- (present day) -  | -  +-A---foo --- Pike 7.3.22 -  -  Lookup of identifier "foo" in B(): -  -  B-+-foo All versions of Pike -  | -  +-A---foo -  - o Thread.Condition()->wait() -  This function takes a mutex lock to unlock while it waits on the -  condition. That argument was previously optional, but not any -  more. The reason is that any code that leaves it out will always -  contain a race; it doesn't work to e.g. rely on the internal -  interpreter lock in this case. -  - o Protocols.HTTP -  All methods in Protocols.HTTP that take a header mapping can now -  handle array values (signifying multiple headers of that type). -  - o Protocols.LDAP.client -  The return code from all methods was changed to follow Pike's -  logic better. 0 is now a failure. The old behavior is emulated in -  a compatibility layer. -  - o dirname -  Now correctly returns a directory instead of just stripping the -  part after the nearest directory separator. -  - o default_yp_domain -  The EFUN default_yp_domain is now only available as -  Yp.default_domain. -  - o clone/new -  The functions clone and new have been removed. Instead of doing -  clone(x) or new(x), now do x() if x is a program and ((program)x)() -  if x is a string. -  - o LR -  LR has been moved to Parser.LR and the API has been changed -  slightly to conform to current API practice, e.g. regarding casing -  of symbols. -  - o wmml documentation removed -  Use the documentation in the refdoc directory instead. -  - o .build_lobotomize_crypto removed -  Use the Makefile target lobotomize_crypto to lobotomize Pike. -  Should preferably be executed in an unused tree straight from CVS. -  -  +    Compatibility changes without backward compatibility:   -----------------------------------------------------    - The following changes were considered bugfixes and have no backwards - compatibility layer. +     - o enum and typedef have implicit local binding -  enums and typedefs now always have static binding. In 7.2 they -  could sometimes be dynamically bound. -  - o Image.Layer modes modified -  Alpha channel handling for modes add, subtract, multiply, divide, -  modulo, invsubtract, invdivide, invmodulo, difference, max, min, -  bitwise_and, bitwise_or, bitwise_xor, screen and overlay modified so -  that the source layer alpha channel copied to the destination layer -  alpha channel rather then mixed with the current layer alpha channel: -  -  aD=aS -  -  rather then the behavior before: -  -  aD=(aL+(1-aL)*aS) -  -  (which is the behavior of the 'normal' mode.) -  -  Bug fixes in the above modes so that alpha r,g,b channels -  are handled properly (separately). -  -  Bug fixes in equal, not_equal, less, more, less_or_equal, and -  more_or_equal modes so that the alpha channel is handled as -  documented (which is, in fact, as above; aD=aS). -  -  Bug fix in divide and invdivide to actually do what the modes are -  supposed to do (rather then just black the layer). -  -  And while on it, adding some modes: -  -  'imultiply' - D=(1-L)*S -  'idivide' - D=S/(1-L) -  'invidivide' - D=L/(1-S) -  -  'value_mul' - multiplying the source layer value -  (as in h,s,v) with the current layer value to the destination -  layer ("true burn"). -  -  +    C level/development changes:   ----------------------------    - o Some global symbols have been renamed to avoid name clashes. -  sp -> Pike_sp -  fp -> Pike_fp -  fatal -> Pike_fatal -  empty_string -> empty_pike_string +     - o --with-internal-profiling -  - o Module symbols not available from other modules. -  -  +    Bugs fixed:   -----------    - o Reworked trampolines to cause less circular references. (solves 1937) +     - o Works with Autoconf 2.50 -  - (To browse bug tickets, either visit - http://community.roxen.com/crunch/ - or append the ticket id to - "http://bugs.roxen.com/" for an address directly to the ticket - itself.) -  -  -  +    Uncategorized misc changes:   --------------------------- - o it is possible to change predefines without forking a new pike - o #pragma save_parent - o #pragma dont_save_parent (overrides constant __pragma_save_parent__) - o dont_dump_module *FIXME: grubba* - o C modules can no longer call functions in other dynamic C modules directly -  FIXME: mast, grubba? - o It is possible to inherit pike programs from C programs. - o Separate weak flags for indices and values in mappings - o Added low lowel glue for the Ffmpeg library. -  -  - o Calendar.verify *FIXME: remove?* -  - Nilsson does lib: -  - master.pike - - add_predefine/remove_predefine - - Improved handling of module cross dependencies. -  -  - Local -  - Multiset -  - Pike.Backend - Pike.Security - Pike.BacktraceFrame - Pike.WEAK_INDICES, WEAK_VALUES, WEAK -  - String.Elite - String.SingleReplace - String.Replace - String.SplitIterator - String.soundex - String.Buffer - String.HTML - String.int2char - String.int2hex - String.expand_tabs - String.int2roman - String.int2size -  - Audio -  - Locale.Language -  - MIME.ext_to_media_type -  - Parser.decode_numeric_xml_entity - Parser.get_xml_parser - Parser.parse_html_entities - Parser.XML.NSTree -  - Protocols.SNMP now works - Protocols.XMLRPC -  - Web.Crawler +